Reputation: 313
I am working on a notification component in which I have an array of "error" objects and iterate through them using *ngFor
. My issue is that Angular won't pick up the changes to the array when I mutate it inside a subscription.
My code is the following:
ngOnInit() {
this.store.select().pipe(
map(state => state.error),
filter(error => !!error),
map(error => ({text: error, display: 'block'}))
).subscribe(error => {
// this does not get detected
this.errors.push(error);
setTimeout(() => {
error.display = 'none';
}, 4000)
});
// this gets detected
this.errors.push({
text: 'asd',
display: 'block'
})
}
And the related html:
<div class="notification-wrapper">
<div *ngFor="let error of errors" [style.display]="error.display" class="notification is-danger has-text-right">
{{ error.text }}
</div>
</div>
The weird thing is that if I replace the subscription with a setInterval
in which I constantly add dummy errors, the changes are caught by Angular and it behaves normally.
Can someone explain to me why it works this way, and maybe how to fix this? Thank you.
Upvotes: 1
Views: 421
Reputation: 214047
Looks like your code is executed outside of Angular zone. You can force to run it inside:
import { NgZone } from '@angular/core';
constructor(private ngZone: NgZone) {}
...
this.store.select().pipe(
map(state => state.error),
filter(error => !!error),
map(error => ({text: error, display: 'block'}))
).subscribe(error => {
this.ngZone.run(() => {
this.errors.push(error);
setTimeout(() => {
error.display = 'none';
}, 4000)
});
});
Upvotes: 2