When dealing with If/Then logic using Observables, it can sometimes be challenging, as demonstrated in your question. For a detailed discussion on this topic, you can check out this article.
You've already received some answers that may work in specific scenarios, and I was initially going to leave the task of helping you to others. However, your query about adding more conditions intrigued me. This led me to search for an observable/functional pattern that is not only easy to read but also allows for effortless extension when introducing new conditions in the future. Your thought-provoking question prompted me to dive deeper into finding a suitable solution.
I decided to implement the pattern suggested in the aforementioned article to address your issue. Although I assumed in my code that you intended for the contact to be updated when the user is NOT new, please note that I have not extensively tested this solution through different scenarios. Ideally, I would prefer to validate my approach by creating test cases on Stackblitz, but unfortunately, time constraints prevent me from doing so at the moment. Nevertheless, the pattern I followed involves creating branches for all possible paths within the If/Then logic, making it easy to incorporate additional actions using `tap()` if required.
The essence of this pattern lies in the `merge()` function utilized at the end. By merging two observables into a single one, we ensure that upon completion of either observable, the `updateContact()` function will execute. In this context, due to the filter condition of `isNewUser()`, only one observable remains active, preventing both from completing simultaneously. However, remember to include a `take(1)` if you wish to prioritize the first asynchronous response in other implementations of this pattern.
In addition, I included subscribe and unsubscribe functions to adhere to best practices.
onSomeEventSub : Subscription; // variable at component scope for later unsubscribing
onSomeEvent() {
const contact: IContact = {
...this.userForm.value
};
const duplicateUserSearch$: Observable<boolean> =
this.userService.duplicateUserSearch(contact.email, contact.userName).pipe(
map(result => (result.result === '')));
const source$ = of(0).pipe(
share()
);
const isNewUserAndIsDupe$ = source$.pipe(
filter(() => isNewUser()),
mergeMap(() => duplicateUserSearch$),
filter(res => res)
);
const isNotNewUser$ = source$.pipe(
filter(() => !isNewUser())
);
this.onSomeEventSub = merge(isNewUserAndIsDupe$, isNotNewUser$).pipe(
mergeMap(() => this.userService.updateContact(contact))
).subscribe(res => this.activeModal.close(res));
}
ngOnDestroy() {
if (this.onSomeEventSub) this.onSomeEventSub.unsubscribe();
}