Issue
public lotId$ = new Subject<number>();
@Input() public set lotId(value: number) {
this.lotId$.next(value);
};
public results$ = this.lotId$.asObservable().pipe(
skipWhile(lotId => !lotId),
switchMap(lotId => this.logicService.getMappedTakeOffTasksForLot(lotId)),
tap(console.log)
);
In the code above, results$ does not emit every time lotId$ emits. Anyone know why? the code runs over results$ once when the component is created and then never again.
EDIT: The source emits 58.
EDIT: It works when I change from Subject to BehaviorSubject. Why? I wish I tried that sooner.
Solution
results$ does not emit every time lotId$ emits.
Subscriptions to results$ that occur before lotId$ emits, will receive those values. To put it another way, late subscribers don't receive prior values (by "late subscriber" I mean subscription after some emissions have occurred).
Assuming you are using async pipe in your template, the subscription of results$ doesn't happen until after the view has been initialized, but the @Input() setters are called before that happens.
You will find that if you subscribe in the constructor (just for experimentation), the derived results$ will in fact emit the initial values.
So, it should be clear why changing to BehaviorSubject works; Upon subscription, it emits the latest previous value to new subscribers.
However, a BehaviorSubject requires a default value (which will of course be emitted to new subscribers). It may not always be appropriate to emit a default value, so you could instead use ReplaySubject(1), which will also emit previous value to new subscribers, but doesn't require a default value.
The image below shows the output received by the template based on the type of subject that is used (Subject / ReplaySubject / BehaviorSubject):
If a component has an optional @Input(), I use BehaviorSubject since a default value is needed. If the input is required I use ReplaySubject(1), so my logic is not executed unless the consumer provides the input.
Here's a little StackBlitz where you can see the order of the Angular lifecycle hooks and when the subscriptions occur.
Answered By - BizzyBob

0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.