Reputation: 3
I have two observables. How do I execute them sequentially and get the completed event one after another? I've tried concatMap, but it seems didn't work as I expected.
this._activatedRouteService.queryParams
.pipe(
concatMap((params) => {
console.log('start');
if (typeof params['q'] === 'string') this._searchQuery = params['q'];
else this._searchQuery = null;
return this._postService
.searchPosts(this._searchQuery!)
.pipe(finalize(() => console.log('inner finalize')));
}),
finalize(() => {
console.log('outer finalize');
})
)
.subscribe(
(response) => {
this._posts = response?.data ?? this._posts;
},
(error) => {
if (error instanceof HttpErrorResponse) {
this._snackBarService.open(
'Failed to fetch posts.\n' +
(error.error?.message ?? 'Unknown error.'),
undefined,
{
duration: SnackBarConfig.ERROR_DURATIONS,
}
);
} else {
this._snackBarService.open(
'Failed to fetch posts.\nUnknown error.',
undefined,
{
duration: SnackBarConfig.ERROR_DURATIONS,
}
);
}
},
() => {
console.log('outer complete');
}
);
But outer finalize
or outer complete
is never called.
Upvotes: 0
Views: 53
Reputation: 1852
The reason outer finalize
is never logged is that _activatedRouteService.queryParams
never completes. It's a hot observable.
If you want the observable to complete after you execute the inner observable once, I recommend the take()
operator. It will "take" any number of values emitted from the observable before sending a complete signal.
Try adding take(1),
on the line before your concatMap()
.
Upvotes: 1