See this plunkr for an illustration: https://plnkr.co/edit/Tm4AW0sU0pumBA8I?open=lib%2Fapp.ts&deferRun=1
Component 1 where i declare everything in the class initializer:
@Component({
template: '{{ data$ | async | json }}',
selector: 'app-data'
})
export class AppData {
readonly id$ = new Subject();
readonly data$ = this.id$.pipe(
switchMap(id => of(`id = ${id}`))
);
@Input()
set id(val: number) {
this.id$.next(val)
}
}
And Component 2 where I create the observable onInit:
@Component({
template: '{{ data$ | async | json }}',
selector: 'app-data-oninit'
})
export class AppDataOnInit implements OnInit {
@Input()
id: number;
data$: any;
ngOnInit(): void {
this.data$ = of(`id = ${this.id}`)
}
}
I am trying to declare the observable in the component contructor or class initialzier but the async pipe is not subscribing to it there. However if I instanciate the observable in ngOnInit it works as expected.
I have been searching all day for an explanation for this but come up empty. What is the missing puzzle piece here?
I feel like it makes more sense to declare the observables when the class is created.
The async pipe is subscribing to your data$
, but this subscription is happening after id$
has emitted. If you want late subscribers to receive prior emisssions, you can use a ReplaySubject
instead of a plain Subject
:
readonly id$ = new ReplaySubject(1);