Home > database >  Rxjs concat Observable with condition
Rxjs concat Observable with condition

Time:12-09

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 => {
  // ...
});
  • Related