Reputation: 81
@Component({
selector: 'app-comment-section',
templateUrl: './comment-section.component.html',
styleUrls: ['./comment-section.component.css']
})
export class CommentSectionComponent implements OnInit, OnDestroy {
@Input()
private commentable: Commentable;
private commentRoom;
private comments: Comment[] = [];
private onNew: Subscription;
private onDelete: Subscription;
constructor(private service: CommentingService, private http: HttpClient) { }
ngOnInit() {
this.commentRoom = this.service.joinCommentsRoom(this.commentable.uuid);
this.http.get<CommentsResponse>(this.commentable.url).subscribe(res => {
this.comments = res.comments.rows;
});
this.onNew = this.commentRoom.newComment$.subscribe((comment) => {
this.comments.push(comment);
})
this.onDelete = this.commentRoom.deletedComment$.subscribe((uuid) => {
console.log('Comment deleted...')
this.comments = this.comments.filter(comment => {
return comment.uuid != uuid;
});
})
}
ngOnDestroy() {
this.onNew.unsubscribe();
this.onDelete.unsubscribe();
this.commentRoom.reconnect.unsubscribe();
}
}
I have a comment section, that is using a commenting service to get observables that emit new and deleted comments. Everything seems to work, except that the view doesn't re-render when this.comments is updated as a comment is created or deleted. I can see that the values are emitted with the console.log().
This is what the ngFor looks like in the view:
<app-comment class="comment" *ngFor="let entity of comments" [entity]="entity"></app-comment>
Is there something I'm doing wrong that is causing the view to not update when the array changes?
Kind regards, Axel
Upvotes: 1
Views: 4160
Reputation: 7733
The NgForOf
directive tracks by the default value, the value can still be the same even if the subvalues are changing: an [Object]
is [Object]
even after changing some nested values.
You can create a custom tracking function to specify what should be used to track the values :
<app-comment class="comment" *ngFor="let entity of comments; trackBy: trackByFn"
[entity]="entity">
</app-comment>
The function implementation must return what makes the entity unique :
trackByFn(index, entity) {
return entity.id;
}
There is a running example in the angular.io documentation.
Upvotes: 1
Reputation: 31
Try separating the ngFor from the component you are attempting to iterate through.
<div *ngFor="let entity of comments">
<app-comment class="comment" [entity]="entity"></app-comment>
</div>
Sometimes, angular's onchanges hook does not register updates in cases where the child components are not directly visible
Upvotes: 1