-1

I noticed that some of my tap(...) invokations won't log to console, so I investigated further and found that an inner piping seems to kill off the outer piping. For instance, the code below, will show inner but won't show outer.

return this.http.get<{ token: string }>(url)
  .pipe(

    tap(_ => console.log("outer")),

    switchMap(_ => {
      ...
      return of(id);
    }),

    catchError(_ => {

      const urlLocal = url.replace(domainProd, domainDev);
      return this.http.get<{ token: string }>(urlLocal)
        .pipe(

          tap(_ => console.log("inner")),

          switchMap(_ => {
            ...
            return of(id);
          })

        );
    })
  );

I'm not sure I understand how to explain it nor how to infer this behavoir from the docs for tap. As far I figure, the tapping is piped to occur prior to the call invokation and, hence, prior to any error being detected.

Apparently, I'm mistaken somehow but I'd like to see it documented or explained somehow and, obviously I failed to find that information too.

As for the structure, if it's surprising, we have an environment on the server that works with the outer and, if run locally, fails, switching to the inner one. Finally, I'm getting a token from which I'm getting sub only, switching the map to the simple string and returning it as an observable.

Konrad Viltersten
  • 36,151
  • 76
  • 250
  • 438
  • The tap operator takes up to 3 callbacks. The first is only called in case a (success) value is emitted, but not when the observable goes in errror. Try this tap( result => console.log("outer next", result), err => console.log("outer error", err), ) – mcoomans Jul 07 '20 at 22:16
  • In case you would be using RXJS version 6, I personally find this site a much better resource: https://rxjs-dev.firebaseapp.com/api/operators/tap – mcoomans Jul 07 '20 at 22:22
  • 1
    Or this: https://rxjs.dev/api/operators/tap – DeborahK Jul 07 '20 at 22:43
  • 1
    @mcoomans That should be posted as a reply to be accepted as correct answer. I have two follow-ups to it and I'd prefer to post them to an answer. Can you repost as such, please? And feel free to inject the link by DeborahK, preferably with a short mention on the difference between them as well as why the one I've been using is not to be preferred in RXJS 6 (which is the one I'm using as I installed a new distribution of Angular). – Konrad Viltersten Jul 08 '20 at 06:49
  • @DeborahK Would you be able to mention a few words on why the resource you've suggested (and the one that mcoomans did too) are better suited than the one I linked to, as well as which of your suggestion is to be preferred when? – Konrad Viltersten Jul 08 '20 at 06:50
  • 1
    The `rxjs.dev` site is the official site for the RxJS library and is maintained by the same team that maintains RxJS. (My link is newer, the firebaseapp link was the older reference) You can see that this documentation is included in the RxJS github repo here: https://github.com/ReactiveX/rxjs/tree/master/docs_app – DeborahK Jul 08 '20 at 16:05

1 Answers1

1

The tap operator takes up to 3 callbacks. The first one is called in case a (success) value is emitted, but not when the observable goes in error. Try this as your first tap operator:

 tap( 
   result => console.log("outer next", result), 
   err => console.log("outer error", err), 
 )

In case your first http call fails, you should see a log of "outer error" before any code inside your catchError operator is called.

Assuming your are learning the latest RXJS 6, I would recommend using rxjs.dev as your first source of reference. (Thanks to @DeborahK for that link).
The site that you referred to www.learnrxjs.io has a nice primer, but once you get the basic concepts I find its documentation of operators too limited. The official rxjs.dev site documents their full interface, describes their behaviour also for edge cases, and typically provides a similar number of code samples.

mcoomans
  • 116
  • 4
  • I'm getting the impression that placing `tap(...)` first of all doens't really matter, does it? It's going to react to successful/failed invocation to the API. Am I correct there or still confusing things? I'm thinking that the reactive observation of the call's outcome is independent of switch-mapping it to the next stage of data format. Can you confirm/refute that statement, please? – Konrad Viltersten Jul 10 '20 at 15:53
  • The presence of that first `tap(...)` doesn't effect the observations in the `switchMap` operator, because a `tab(..)` leaves the observable sequence of pushed values unchanged. Your switchMap on the other hand does impact the observable. Before the SwitchMap, you an Observable<{token:string}> ; after the switch you get an Observable . If you would insert another tab(..) with console.logs after that switchMap, you would see different values logged in that second tab() compared to the first tab(). – mcoomans Jul 13 '20 at 21:54