0

I have a little problem with subscribing my Observable

I have one one combined Observable:

private selectedEntryId$ = new Subject<number>();
private entries$ = new Subject<MappingEntry[]>();

private selectedEntry$ = Observable.combineLatest(
    this.entries$,
    this.selectedEntryId$,
    (entries: MappingEntry[], id: number) => {
        return entries.find((entry: MappingEntry) => {
            return entry.id === id;
        });
    });

I try do API call every time, when my selectedEntry$ has next value and subscribe result in this way:

constructor(private checkService: CheckService) {
    this.subscribeLengthCalculator();
}

subscribeLengthCalculator() {
    this.subscriptions.add(
        this.selectedEntry$
            .switchMap((entry) => {
                return entry ? this.checkService.calculateLinesLength([entry.value]) : Observable.empty();
            }).subscribe(([calculation: CalculationObject]) => {
                    console.log(calculation);
                    this.calculation = calculation;
             })
    );
}

First time when selectedEntry$ has next value, console.log throw to the console correct API result, but in my html calculation has null value. When selectedEntry$ has second next value, console.log throw to the console correct API result too but in html show mi previous value. Anyone can explain me this behaviour and tell me what I should do to showing current data in html? It's very strange behaviour.

Jaroslaw K.
  • 5,224
  • 2
  • 39
  • 65
  • use `Behavior Subject` see [this](https://stackoverflow.com/questions/43348463/what-is-the-difference-between-subject-and-behaviorsubject) – Vikas May 24 '18 at 19:13

1 Answers1

0

Quoting learnrxjs "Be careful though, you probably want to avoid switchMap in scenarios where every request needs to complete".

"The main difference between switchMap and other flattening operators is the cancelling effect", that is why when selectedEntry$ has second next value, it show your previous value. The source observable (this.selectedEntry$) a;ready complete, the subscription is just active for the Observable coming from this line:

return entry ? this.checkService.calculateLinesLength([entry.value]) : Observable.empty()

So, with that said, I recommend you try concatMap instead of switchMap:

subscribeLengthCalculator() {
    this.subscriptions.add(
        this.selectedEntry$
            .concatMap((entry) => {
                return entry ? this.checkService.calculateLinesLength([entry.value]) : Observable.empty();
            }).subscribe(([calculation: CalculationObject]) => {
                    console.log(calculation);
                    this.calculation = calculation;
             })
    );
}

but as a matter of fact, I love pipeline operators, so the answer will be:

import { concatMap } from 'rxjs/observable/concatMap';

subscribeLengthCalculator() {
        this.subscriptions.add(
            this.selectedEntry$
                .pipe(
                    concatMap((entry) => {
                        return entry ? this.checkService.calculateLinesLength([entry.value]) : Observable.empty();
                    })
                ).subscribe(([calculation: CalculationObject]) => {
                    console.log(calculation);
                    this.calculation = calculation;
                })
        );
    }
Luillyfe
  • 6,183
  • 8
  • 36
  • 46