I have an Observable that is backed by a private BehaviorSubject. On the first emit, I would like to initialize the BehaviorSubject from an async call, but I can't come up with a great pattern to do so. As far as I can tell, BehaviorSubjects can't be initialized from an async function.
What I have so far is:
protected _monkeyNames = new BehaviorSubject<Set<string>>(null);
MonkeyNames$: Observable<Set<string>> = this._monkeyNames.pipe(
switchMap(async (nodes) => nodes ?? (await this.getMonkeyNames()))
);
protected async getMonkeyNames(): Promise<Set<string>> {
const names = new Set(await this.stateService.getMonkeyNames());
return names;
}
But this won't set the BehaviorSubject, it will only be set when I call setMonkeyNames later to save a new value. If I do call .next() inside of getMonkeyNames, the Observable will emit again, which could result in an eternal loop if names is null.
It might be my own ignorance when it comes to rxjs, but does anyone have a pattern they use for this?
Edit:
I should mention that this is a service, and I won't have access to ngOnInit()
BehaviorSubjectis useful only when there is a initial value. Since you don't have any,ReplaySubjectorSubjectcan be used. Also initializing BehaviorSubject with null, when type clearly restricts to Set<...>, is just an error.If your service returns promise of some value, convert it to Observable with
fromand process in operator chain.