I'm trying to create a blog system that increments the amount of views a certain post has everytime the post is viewed. I'm using firebase for the database and when I go to retrieve the value of the post views, then update it, it continuously increments the value and freezes my browser.. Below is the code I have for it.. Any suggestions?
@Component({
templateUrl: './post.html',
styleUrls: ['./post.css']
})
export class Post {
post: any;
constructor(db: AngularFireDatabase, router: Router, route: ActivatedRoute){
route.params.forEach(p => {
let id = p['id'];
if(id != null){
let views = 0;
let postRef: AngularFireObject<any> = db.object('/Posts/'+id);
this.post = postRef.snapshotChanges().subscribe(actions => {
this.post = actions.payload.val();
let v = this.post.views + 1;
postRef.update({
views: v
})
});
}else{
router.navigate(['/']);
}
});
}
}
The working sample @ https://angular-5urevo.stackblitz.io/
import { Component, OnDestroy } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { AngularFireDatabase, AngularFireObject } from 'angularfire2/database';
import { Subscription} from 'rxjs';
export class PostComponent implements OnDestroy {
post: any;
postRef: AngularFireObject<any>;
postRefValueSub: Subscription;
postRefUpdateSub: Subscription;
constructor(protected db: AngularFireDatabase, protected router: Router, protected route: ActivatedRoute) {
if(!this.route.snapshot.params['id']) {
this.router.navigate(['/']);
return;
}
this.postRef = db.object(`/posts/${this.route.snapshot.params['id']}`);
/* updating post info to view ... */
this.postRefValueSub = this.postRef.valueChanges().subscribe(value => this.post = value);
this.update();
}
/* updating post views .... */
update(value?: any){
/* increment post's view and unsubscribe to prevent nested looping... */
this.postRefUpdateSub = this.postRefUpdateSub || this.postRef.valueChanges().subscribe((value) => {
this.postRefUpdateSub = this.unsubscribe(this.postRefUpdateSub);
this.post = value || this.post || { views: 0 };
this.post.views++;
this.postRef.update(this.post);
});
}
/* helper to unsubscribe from a subscription ...*/
unsubscribe(subscription: Subscription) : Subscription {
if(!subscription) { return subscription; }
if(!subscription.closed) { subscription.unsubscribe(); }
return null;
}
/* unsubscribing from all subscriptions ... */
ngOnDestroy(){
this.postRefValueSub = this.unsubscribe(this.postRefValueSub);
this.postRefUpdateSub = this.unsubscribe(this.postRefUpdateSub);
}
}