I declare a collected observable in my ts file like so:
getData = (): Observable<IBookingState> => {
return combineLatest(this.user$, this.files$).pipe(
map(([user, files]) => ({ user, files })),
tap(v => {
this.bookingForm.get('displayName')!.setValue(v.user.displayName)
this.dataSource = new MatTableDataSource(v.files)
this.dataSource.connect()
}),
filter(v => !!v),
takeUntil(this.destroyed$),
tap(v => console.log(v)),
// startWith({ files: [] as MediaFile[] } as IBookingState),
finalize(() => {
this.loadSrv.setLoading(false)
})
)
}
This contains a user object and file[] of input files, that i get from a service as a behavior subject like so:
files$: Observable<MediaFile[]> = this.bookingSrv.files$.pipe(
takeUntil(this.destroyed$),
startWith([])
)
bookingSrv.files$ is just a behavior subject (.asObservable()) with initial value as [], and its being called with | async pipe:
private filesSubj$ = new BehaviorSubject<MediaFile[]>([] as MediaFile[])
files$ = this.filesSubj$.asObservable()
... // in component html:
*ngIf="data$ | async as data"
// data$ contains a mapped observable with the files$
What is wrong: When i go from a random other component into this component, the files$: Observable<[]> is cold, and my component is therefore not rendered.
What should happen: The files observable is being unwrapped with async pipe in HTML, but contains just an empty array (no files).
Other: When i refresh the component, everything is fine and i see the console output as empty array ([]).
How to specify and trigger an observable with empty array as initial value?
EDIT: I've been suggested to use the withlatestfrom operator, so i did that:
return this.user$.pipe(
withLatestFrom(this.files$),
map(([user, files]) => ({ user, files })),
tap(v => {
this.dataSource.data = [...v.files];
this.bookingForm.get('displayName')!.setValue(v.user.displayName)
}),
filter(v => !!v),
)
Still no different. The files$ Obs. is cold, not triggered from routing into the component, but will get hot upon refreshing the page.