Search code examples
angularrxjsrxjs-observables

Chaining higher order mapping operators - how does it work under the hood?


I need to reset the data in my database which involves the actions -

  1. fetch all data
  2. delete all data
  3. create new data

in sequence, and I have the following three methods in my service -

getAllData(): Observable<IUser[]> {
    //
}

clearAllData(users: IUser[]): Observable<boolean> {
    //
}

generateNewData(cleared: boolean): Observable<IUser[]> {
    //
}

In my component, I used them like below -

resetData(): void {
    this.service.getAllData()
        .pipe(
            concatMap(p => this.service.clearAllData(p)
                .pipe(
                    concatMap(p => this.service.generateNewData(p))
                ))
        )
        .subscribe(
            p => {
                this.dataSource = p;
            },
            e => {
                console.log('Error: ', e)
            }
        );
}

It works. It also works if I used them like -

resetData(): void {
    this.service.getAllData()
        .pipe(
            concatMap(p => this.service.clearAllData(p)),
            concatMap(p => this.service.generateNewData(p))
        )
        .subscribe(
            p => {
                this.dataSource = p;
            },
            e => {
                console.log('Error: ', e)
            }
        );
}

I'm just trying to understand the difference between how this two approaches work behind the scene.

As far as I know, higher order mapping operators subscribes to their outer observable. Therefore, in the first approach -

  • the first concatMap() subscribes to the observable returned by the service.getAllData() method, and
  • the second concatMap() subscribes to the observable returned by the service.clearAllData() method

(Please correct me if I'm wrong here).

But in the second approach, shouldn't both concatMap() subscribe to the observable returned by the service.getAllData() method?

How are the both approach producing the same result then?


Solution

  • Higher order mapping operators automatically subscribe to and unsubscribe from their inner Observable.

    So in both cases, they subscribe to the Observable returned by the service method called within the operator's arrow function.

    Both of these options behave the same because in both cases, concatMap will wait to complete it's operation and emit before moving on to it's pipeable operators OR it's next sibling operator.

    Make sense?