Reputation: 3823
I have the following code to manage users,
@Component({
selector: 'app-user',
template: `
<input [(ngModel)]="newUser"><button (click)="addNewUser()">add</button>
<div *ngFor="let user of users$ |async">
{{user}}
</div>
`
})
export class UserComponent {
newUser: string;
users$: Observable<any>;
private _users = [];
ngOnInit() {
this.users$ = of(this._users);
}
addNewUser() {
this._users.push(this.newUser);
}
}
How does angular know when to update this.users$ in the html when I simply push a new user to this._users array wrapped in rxjs of
? How does angular async pipe detect changes inside an observable?
Upvotes: 2
Views: 11805
Reputation: 21628
You can view the source code here
https://github.com/angular/angular/blob/master/packages/common/src/pipes/async_pipe.ts
It subscribes to the observable.
From the comments in the source
async
pipe subscribes to an Observable
or Promise
and returns the latest value it has emitted.async
pipe marks the component to be checked for changes.async
pipe unsubscribes automatically to avoid potential memory leaks.Looking at your question you are abusing the point of observables. You should not be pushing a new value into the array, you should be making the observable emit a new array. The reason Angular is updating the page has nothing to do with observables but the fact you are using the default change detection strategy it notices the array has changed.
If you were using a BehaviorSubject instead of using of you could call next
addNewUser() {
const users = this.users$.getValue();
this.users$.next([...users, this.newUser]);
}
Observables allow you to use the more efficient on push change detection strategy which will not update the page with what you have done. You would need to replace the array with a new instance of an array for onPush to detect changes.
Upvotes: 5