17

example:

var s1 = Observable.of([1, 2, 3]);

var s2 = Observable.of([4, 5, 6]);

s1.merge(s2).subscribe(val => {
   console.log(val);
})

I want to get [1,2,3,4,5,6]

instead of

[1,2,3]

[4,5,6]

1
  • if i did Observable.forkJoin(s1, s2) i will get [[1,2,3], [4,5,6]] Commented May 23, 2017 at 17:43

6 Answers 6

33

forkJoin works wells, you just need to flatten the array of arrays :

const { Observable } = Rx;

const s1$ = Observable.of([1, 2, 3]);
const s2$ = Observable.of([4, 5, 6]);

Observable
  .forkJoin(s1$, s2$)
  .map(([s1, s2]) => [...s1, ...s2])
  .do(console.log)
  .subscribe();

Output : [1, 2, 3, 4, 5, 6]

Plunkr to demo : https://plnkr.co/edit/zah5XgErUmFAlMZZEu0k?p=preview

Sign up to request clarification or add additional context in comments.

Comments

6

My take is zip and map with Array.prototype.concat():

https://stackblitz.com/edit/rxjs-pkt9wv?embed=1&file=index.ts

import { zip, of } from 'rxjs';
import { map } from 'rxjs/operators';

const s1$ = of([1, 2, 3]);
const s2$ = of([4, 5, 6]);
const s3$ = of([7, 8, 9]);
...

zip(s1$, s2$, s3$, ...)
  .pipe(
    map(res => [].concat(...res)),
    map(res => res.sort())
  )
  .subscribe(res => console.log(res));

Comments

3

Just instead of Observable.of use Observable.from that takes as argument an array and reemits all its values:

var s1 = Observable.from([1, 2, 3]);
var s2 = Observable.from([4, 5, 6]);

s1.merge(s2).subscribe(val => {
   console.log(val);
});

Maybe instead of merge you might want to prefer concat but in this situation with plain arrays it'll give same results.

This will give you:

1
2
3
4
5
6

If you want this as a single array you could append also toArray() operator. Btw, you could achieve the same with Observable.of but you'd have to call it with Observable.of.call(...) which is probably unnecessary complicated and it's easier to use just Observable.from().

1 Comment

what if you have an array of observable arrays? i.e (s1, s2, ..., sN)
2

Maybe you could do this with List instead of Array:

var s1 = Rx.Observable.of(1, 2, 3); 
var s2 = Rx.Observable.of(4, 5, 6); 

and then

Rx.Observable.merge(s1,s2).toArray().map(arr=>arr.sort()).su‌​scribe(x=>console.l‌​og(x))

1 Comment

my sources are arrays, so thats not an option for me
2

The accepted answer from @maxime1992 will now cause deprecation warnings with the current version of RXJS. Here's an updated version:

import { forkJoin, of } from 'rxjs';
import { map } from 'rxjs/operators';

const s1$ = of([1, 2, 3]);
const s2$ = of([4, 5, 6]);

Observable
  .forkJoin([s1$, s2$])
  .pipe(     
    .map(([s1, s2]) => [...s1, ...s2])
  )
.do(console.log)
.subscribe();

Comments

1

For angular version 13, you can use forkJoin as follows:

import { forkJoin, of, map  } from 'rxjs';

const s1$ = of([1, 2, 3]);
const s2$ = of([4, 5, 6]);

forkJoin([s1$, s2$])
  .pipe(     
    .map(([s1, s2]) => [...s1, ...s2])
  )
.subscribe(console.log);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.