Reputation: 12433
First off, here are my import statements for rxjs:
import { Subject, Observable, merge, combineLatest } from "rxjs";
import { map } from 'rxjs/operators';
Here is my rxjs version in package.json:
"rxjs": "^6.5.2"
I have an Observable (this.searchResults$
) which emits the results of a search API request. I now want to do another search and combine the new search results with the old search results, and put them all in this.searchResults$
. this.handleSearch()
returns the observable with the search results
I thought I would do this:
const newSearchResults$ = this.handleSearch(undefined, this.currentPage + x);
merge(newSearchResults$, this.searchResults$).subscribe(x => console.log(x));
But this console logs:
(10) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
(6) [{…}, {…}, {…}, {…}, {…}, {…}]
The second line of the console log needs to contain 16 items. Instead it gets overwritten with the new 6 items.
I looked online why merge does not combine the results and found that I should use combineLatest
:
const newSearchResults$ = this.handleSearch(undefined, this.currentPage + x);
newSearchResults$.subscribe(x => x);
const combinedSearchResults$ = combineLatest(newSearchResults$, this.searchResults$)
.pipe(map(([s1, s2]: Array < any > ) => [...s1, ...s2]));
combinedSearchResults$.subscribe(x => console.log(x));
This does not console.log anything at all and has no errors. What am I doing wrong?
As per Pavel's answer I tried:
const newSearchResults$ = this.handleSearch(undefined, this.currentPage + x);
this.searchResults$.pipe(
mergeMap((d1: any) => newSearchResults$.pipe(map(d2 => [...d1, ...d2])))
).subscribe(console.log);
I can't get anything to console.log with this either.
Upvotes: 3
Views: 2560
Reputation: 875
If you wan't to merge 2 observables you can use mergemap operator. try something like this:
var obs1 = lastData;
var obs2 = newData;
obs1.pipe(
mergeMap(d1 => obs2.pipe(map(d2 => [...d1, ...d2])))
).subscribe(console.log);
Secondly be aware if you use cold or hot observable, because if you use the cold one the value won't be saved and the API will be called each time you subscribe to it. (you can create hot observable from cold with shareReplay operator.
Or you can use BehaviorSubject like in this example: https://stackblitz.com/edit/angular-dkh5ji
Upvotes: 1