Search code examples
rxjsrxjs6rxjs-pipeable-operators

Rxjs: get latest values from multiple observables later after they emitted


I have multiple observables that emit values during the lifetime of the page. For example:

chartData$: Observable;
tableData$: Observable;
filterData$: Observable;

At any time user can click the 'Download' button, and get the JSON combining the values that were last emitted from each of these observables:

downloadButtonClicked$.pipe(
    combine chartData$, tableData$ and filterData$    // <- how do I get latest values here?
).subscribe(([chart, table, filter]) => downloadJson(chart, table, filter))

but the downloadJson function shouldn't be called when any of these 3 observables emit values as part of page lifecycle, only on Download click.

TLDR;

working most elegant solution (as suggested by Mike) https://stackblitz.com/edit/typescript-jm3zma?file=index.ts


Solution

  • You can do it like this:

    combineLatest([chartData$, tableData$, filterData$]).pipe(
      switchMap(result => downloadButtonClicked$.pipe(map(() => result)))
    ).subscribe(([chart, table, filter]) => {
      downloadJson(chart, table, filter);
    });
    

    Whenever chartData$, tableData$, or filterData$ emits a new value it will create a new inner subscription to downloadButtonClicked$ passing down the new data.

    Note: the subscription will not be created until all of chartData$, tableData$, and filterData$ have emitted their first value. If you need the download to still trigger in this case then you can use defaultIfEmpty.