Reputation: 488
Given a template that looks like something like this
<some-component
*ngIf="someColdObservable$ | async"
[result]="someColdObservable$ | async"
></some-component>
and an observable that looks like this:
someColdObservable$: this.store.pipe(
select(isAllowedToDoThis),
filter(Boolean),
flatMap(() => apiRequest())
);
The someColdObservable$
gets subscribed to twice (as expected), which in turn issues two api calls (this is obviously a code smell, but let's disregard that at the moment).
In this scenario some-component
does not contain any null checks, and AsyncPipe
will return null if apiRequest
has not emitted a value before the AsyncPipe
is evaluated in the template resulting in some-component
throwing a cannot access x of null
(as [result]
is still null at this point) see AsyncPipe
source for reference.
This is all expected behaviour (or at least after reading the source) however, when I try to mitigate the issue with making two requests by adding the shareReplay
to someColdObservable$
I also fix the issue of [result]
being null before the apiRequest()
emits a value. This makes little sense to me as I would expect AsyncPipe
to still return a null
_latestValue
here, leaving the cannot access x of null
error unfixed. But for some reason adding shareReplay
fixes both of the aforementioned issues.
This is similar to Angular observable behavior odd when shared however, there is still the unanswered question of why shareReplay
fixes the issue.
Would someone be able to point out what I am missing here and why AsyncPipe
no longer returns null
before apiRequest()
emits a value?
Appreciate any pointers and input, thanks!
Upvotes: 1
Views: 1812
Reputation: 691845
First scenario:
Second scenario:
A better solution than using shareReplay would be to store the result of the async pipe in a variable and use it:
<some-component
*ngIf="someColdObservable$ | async as result"
[result]="result"
></some-component>
Upvotes: 6