0
votes

I'm developing an angular 7 app, I know that nested subscribe functions are an anti pattern but using correctly the transformation operators (like mergeMap, switchMap ...) inside a pipe function I could always avoid it. I'm facing a situation in which I can't understand how the inner observable works. I have a form of filters which are fully intialized after an event signaled by an observable, after this event I have to listen form changes via .valueChanges on the formGroup, format the filters and finally filter the results.

this.filters.categoriesReady.asObservable()
      .pipe(
        tap((categories) => {
          this._createControlsCategories(categories);
          this.categories = categories;
          console.log('higher order observable');
        }),
        switchMap(() => this.filterForm.valueChanges),
        switchMap(filtersRaw => this._formatFilters(filtersRaw)),
        takeUntil(this.unsubscribe)
      )
      .subscribe(
        filtersFormatted => {
          this.filterResults(filterFormatted);
          this.filterUpdated.emit(true);
        }
      );

I thought that the inner stream this.filterForm.valueChanges would not work because it is dependent on the the event this.filters.categoriesReady which is fired only once (indeed the console.log print out once) and so I thought that it was not always listening as I would have liked. Instead the code in the subscribe function is executed each time there are changes applied to the filters. Can someone explain it to me?

1
By doing switchMap you actually subscribed to observable and you will be notified each time. It is not like it will unsubscribe after first emit. If you want to get only the latest value from particular observable try using withLatestFrom. - Yevgeniy.Chernobrivets
I would recommand reading switchMap documentation, because it might not be doing what you want it to do. - Morphyish
switchMap works like this: let's say you're only interested in the latest JS trends. And each time a new JS framework goes out, you want to forget about all the previous ones and become an expert on the newest trendy framework. So you subscribe the the "new JS framework is out" observable to be notified when a new framework goes out. And every time one goes out, you unsubscribe from the blog about the old framework, and subscribe to the blog about the newest one. So, in your case, every time categoriesReady emits, you subscribe to all the changes emitted by your form. - JB Nizet

1 Answers

1
votes

switchMap switches into a new inner observable after the outter observable emits, so the outter only needs to emit once. The behavior of switchMap though is that it cancels and resubscribes to the inner observable everytime the outter observable emits.

TBH, in this case, you seem to just be using the outter observable to guarantee the inner observable isn't subscribed until categoriesReady observable emits. I'm not sure what the reasoning behind that is, when you could't just subscribed to both independently since they don't seem to be reliant upon eachother.., nor am I sure why _formatFilters returns an observable.

but hope that clears up the switchMap behavior