The task
I have 3 observable http1$
http2$
http3$
which are http requests.
const http1$ = this.myService.someFnReturnAnObservale({});
I have another observable isAuth$
as my stream source.
I need to get response from http3$
.
Context
In order to make http3$, http2$ have to response something first.
Depend on isAuth$
value, if it emits true
then http2$ also has to wait http1$ to response something, if it emits false
, then no need http1$.
By something I mean either success or error, so I can apply some logic to it, and decide to stream to next observable or not.
Coding
- create an observable to handle logic from http2$ to http3$
const http23$ = http2$.pipe( first(), map(res => { // some logic, return boolean flag }), catchError(err => { return of(false); // in case http2$ response with error, also return false }), map(res => { // if response (which is the flag above) is false // pop an message return res; }), filter(res => res === true), // only subscribe to http3$ after this mergeMap(res => http3$), );
- I have 2 logic with the
isAuth$
, so:
const initWithoutAuth$ = of(http23$); // no need http1$ const initWithAuth$ = http1$.pipe( first(), map(res => { // some logic, return boolean flag }), catchError(err => { return of(false); // in case http1$ response with error, also return false }), map(res => { // if response (which is the flag above) is false // pop an message return res; }), filter(res => res === true), // only subscribe to http23$ after this mergeMap(res => http23$) );
- Whenever
isAuth$
emits new value, I'd like to cancel the current stream and start using another
isAuth$.pipe( switchMap(res => // does this really cancel curernt stream (http requests) to start over within the other one? res ? initWithAuth$ : initWithoutAuth$ ) ).subscribe( res => { console.log(`init`, res); // not the desired result yet }, err => {} );
- I expect
http3$
response when I subscribe at last step, but I got a weird observable. - How can I handle http observable response error properly in this situation? (duplicated code whenever I try to handle response and catch error of previous one)
CodePudding user response:
What I think is wrong is this line
const initWithoutAuth$ = of(http23$);
With this line you basically say that initWithoutAuth$
is an Observable which notifies (emits) another Observable, i.e. it notifies http23$
.
It looks to me that initWithoutAuth$
should be simply set to http23$
and not to of(http23$)
.
If you do this, you can also remove catchError
from initWithAuth$
and initWithoutAuth$
and add it to the final Observable chain, like this
isAuth$.pipe(
switchMap(res => // does this really cancel curernt stream (http requests) to start over within the other one?
res ? initWithAuth$ : initWithoutAuth$
),
catchError(err => {
return of(false); // in case http1$ or http2$ response with error, also return false
}),
).subscribe(
res => {
console.log(`init`, res); // not the desired result yet
},
);
As last note. I think that the last
operator you use after each http call is not required. The http client returns an Observable which notifies at most just 1 value and then completes, so the last
operator is redundant.