I'm trying to execute a rest call based on a condition. The call will be executed but, depending on the condition, it will be executed after another rest call. For now, I tried in this way but I'm sure it's not the best way to do it:
if(!checkTokenValidation()) {
this.service.getToken().pipe(
map(response => {
setToken(response);
})
).subscribe(() => {
this.service.search().subscribe(data => {
...
})
})
} else {
this.service.search().subscribe(data => {
...
})
}
I need to do search in every case but, if token is not valid, I need to get new token first. Is there a way to do this without redundant code? Thanks
CodePudding user response:
One approach could be the following:
import { EMPTY, of } from "rxjs";
import { map, tap, switchMap } from "rxjs/operators";
// if token is valid, create an empty observable, else set the observable to the service.getToken api call
var obs$ = checkTokenValidation() ? of(EMPTY) : this.service.getToken().pipe(map(response => setToken(response));
// take the first observable and then map it to a new observable, a.k.a. the response from the service.search api call
obs$.pipe(switchMap(() => this.service.search())
.subscribe(data => {
...
});
CodePudding user response:
It looks like what you're doing relies on some state you're not managing explicitly. That's fine, but it's always going to look slightly awkward in a declarative library like RxJS. You need the token, but then I immediately ignoreElements
.
That might read strangely to you, but something like this should work:
( checkTokenValidation() ?
EMPTY :
this.service.getToken()
).pipe(
tap(response => setToken(response)),
ignoreElements(),
concatWith(this.service.search())
).subscribe(data => {
// ...
});