There is following code and I am wondering why Subject.next(1)
emmision is not visible in template whereas BehaviorSubject.next()
emission is visible.
I know that wrapping it inside setTimeout()
fixes it, but I would like to understand it.
I seems, like Subject.next()
is synchronnous and async
pipe does not receive / mark for check.
@Component({
selector: 'my-app',
template: `
<div>Subj: {{ subj$ | async }}</div>
<div>BehavSubj: {{ behavSubj$ | async }} </div>
<div>Interval: {{ interval$ | async }} </div>
`,
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
subj$ = new Subject<number>();
behavSubj$ = new BehaviorSubject<number>(1);
interval$ = interval(1000).pipe(take(100));
ngOnInit(): void {
this.subj$.next(1);
this.behavSubj$.next(2);
}
}
https://stackblitz.com/edit/angular-ivy-crnfgc?file=src/app/app.component.ts
It's not detected because it's to early. Replace all occurrences of OnInit
with AfterViewInit
and it works.
import { Component, AfterViewInit, OnInit, VERSION } from "@angular/core";
import { BehaviorSubject, interval, Subject } from "rxjs";
import { take } from "rxjs/operators";
@Component({
selector: "my-app",
template: `
<div>Subj: {{ subj$ | async }}</div>
<div>BehavSubj: {{ behavSubj$ | async }}</div>
<div>Subj: {{ subj2$ | async }}</div>
<div>BehavSubj: {{ behavSubj2$ | async }}</div>
<div>Interval: {{ interval$ | async }}</div>
`,
styleUrls: ["./app.component.css"]
})
export class AppComponent implements OnInit, AfterViewInit {
subj$ = new Subject<number>();
behavSubj$ = new BehaviorSubject<number>(1);
subj2$ = new Subject<number>();
behavSubj2$ = new BehaviorSubject<number>(1);
interval$ = interval(1000).pipe(take(100));
ngOnInit(): void {
this.subj$.next(1);
this.behavSubj$.next(2);
}
ngAfterViewInit(): void {
this.subj2$.next(1);
this.behavSubj2$.next(2);
}
}
First you have to init the view so that the async pipe is already subscribed. Then you can send a value to a simple subject. A behavior subject is different. It stores its last value. You can first update a behavior subject and then subscribe. That's also the reason why you have to initialize a behavior subject but it makes no sense to initialize a basic subject.
Here is an example.