2

The 2nd concatMap does not get called.

this.apiService.get()
               .pipe(
                   concatMap((data: MyModel) => {
                       if (data) {
                           // the following returns a MyModel Observable
                           return this.apiService.update(data);
                       } else {
                           return empty();
                       }
                   }),
                   concatMap((data: MyModel) => this.apiService.update(this.myOtherData))
               )
               .subscribe(data => log('completed'));

any ideas?

Antediluvian
  • 653
  • 1
  • 6
  • 18
  • 4
    Well, the first one sometimes returns empty. If nothing is emitted by the first concatMap, there is nothing to trigger the second one. It could also be called by an error. Have you debugged your code to understand what happens? – JB Nizet Nov 04 '18 at 12:00
  • Interesting, I would have expected the same behavior as OP – Jota.Toledo Nov 04 '18 at 12:53
  • @JBNizet The first API call returns `undefined` which means the data does not exist. Then the first `concatMap` goes into the `empty()` routine. Are you saying that because of the `empty()`, the 2nd one never gets triggered? – Antediluvian Nov 04 '18 at 21:59
  • Yes. concatMap's documentation says: "An Observable that emits the result of applying the projection function (and the optional deprecated resultSelector) **to each item emitted by the source Observable**" (emphasis mine). It the source observable doesn't emit, the callback function passed to concatMap() is never called. BTW, what would by the value of its `data` argument, since no data is ever emitted? – JB Nizet Nov 04 '18 at 22:03
  • @JBNizet Then I added a `defaultIfEmpty(new MyModel())` just before the first `concatMap` but the `data` in the first `concatMap` is stiff `undefined`. – Antediluvian Nov 05 '18 at 06:44
  • The problem is not that you get undefined in the first concatMap() (well, it's *another* problem). The problem is that if data is undefined, you return empty(), thus preventing the second concatMap callback. So that is the answer to your question. If you're never supposed to receive undefined in the first concatMap, then remove the if/else block, and fix the apiService.get() method, which returns an Observable emitting undefined but should not. – JB Nizet Nov 05 '18 at 07:07

1 Answers1

0

You'd have to double pipe. Take a look here: https://github.com/reactivex/rxjs/issues/4071

timer(10).pipe(
  concatMap(() => from(wait(20)).pipe(
    concatMap(() => {
      console.log('here');
      return from(wait(20)).pipe(
        tap(x => console.log('>', x))
      );
    })
  ))
)
.subscribe(x => console.log('>', x));

You know how concatMap requires an observable to return? Well I just learned that if there is an issue with that source observable concatMap won't fire. I was stumped trying to troubleshoot concatMap when it wasn't the cause.

This is how I troubleshot it too, by sending an empty observable to make sure my setup was correct.

this.sendRequest({'search': "be"}).pipe(
    concatMap(options => {
        console.log(options);
        return of([]);
    })
).subscribe(data => {
     console.log(data);
});
Ben Racicot
  • 5,332
  • 12
  • 66
  • 130