Is there a way to detect the start of the subcription of a rxjs observable within the pipe?
I want to trigger a loading indicator when a http observable (destroyed when respone has been finalized) get subscribed.
Or do I have to create a wrapper observable for this action?
It depends on what RxJS version you're using. With RxJS < 7.3 you can use defer():
defer(() => {
loadingFlag = true;
return this.http.doyourrequest().pipe(
finalize(() => loadingFlag = false),
);
});
Since RxJS >= 7.3 you can use new event handlers for tap():
this.http.doyourrequest().pipe(
tap({
subscribe: () => loadingFlag = true,
finalize: () => loadingFlag = false,
}),
);
since every subscription to http observable causes new http call it is safe to set such flag outside of the pipe, at least it is how I do it.
getSomeData(){
loadingFlag=true;
return this.http.doyourrequest().pipe(finalize(()=>loadingFlag=false));
}
if you really want to go trough sub count(which is always down to 0 after every request due to finalizztion of http obs) check the implementation of refCount() and share() operators which internally counts the subscribers
Edit:
You can encapsulate setting of the flag using dummy observable as an entry point eg
getSomeData(){
return of(null).pipe(
tap(()=>loadingFlag=true),
switchMapTo(this.http.doyourrequest()),
finalize(()=>loadingFlag=false)
)
}
Instead of setting some indicator as a side effect in your stream, try creating an observable that returns the state of your request.
readonly makeRequestSubject = new Subject<RequestParams>();
readonly request$ = makeRequestSubject.pipe(
switchMap(params => this.doRequest(params).pipe(
map(result => ({ params, result, state: 'complete' })),
catchError(error => ({ error, params, state: 'error' }))
startWith({ params, state: 'loading' })
),
startWith({ state: 'notstarted' }),
shareReplay(1)
);
readonly isLoading$ = this.request.pipe(map(x => x === 'loading'), distinctUntilChanged());
readonly results$ = this.request.pipe(map(x => x === 'complete' ? x.results : []));