Rob DePietro
Rob DePietro

Reputation: 324

How to combine two similar RxJS observable object arrays into one array of objects?

I need assistance trying to get two HTTP GET responses that come object arrays and combine them into one object array for example

If possible I would like the array from http using rxjs more than likely to have a response that has all 3 objects in one array

like below

[{...}, {...}, {...}]

.ts

incidents$ = this.incidentService.getAll();
otherIncidents$ = this.otherIncidentsService.getAll();


ngOnInit() {


this.incidents$.subscribe(res => {
 console.log('first http GET request', res)
})

this.otherIncidents$.subscribe(res => {
 console.log('second http GET request', res)
 })

Console

second http GET request [{…}]
0: {incidentNumber: 19418, createdByName: "User", execSummaryFlag: 
false, followupEmail: null, …}
length: 1__proto__: Array(0)
exec-summary.component.ts:140 

first http GET request (2) [{…}, {…}]
0: {incidentNumber: 19380, createdByName: "User", execSummaryFlag: false, 
followupEmail:null, …}
1: {incidentNumber: 19399, createdByName: "User", execSummaryFlag: false, 
followupEmail: null, …}length: 2__proto__: Array(0)

Upvotes: 0

Views: 3073

Answers (5)

Rob DePietro
Rob DePietro

Reputation: 324

Answer to my Question

ngOnInit(){

const incidents = this.incident.getAll();
const otherIncidents = this.otherService.getAll();
forkJoin([incidents, otherIncidents])
.subscribe(res => {
 this.execEntry=[...res[0], ...res[1]];
 console.log(this.execEntry);
})
}

Upvotes: 0

Soham
Soham

Reputation: 725

Take a look at Concat

// RxJS v6+
import { of, concat } from 'rxjs';

concat(
  of(1, 2, 3),
  // subscribed after first completes
  of(4, 5, 6),
  // subscribed after second completes
  of(7, 8, 9)
)
  // log: 1, 2, 3, 4, 5, 6, 7, 8, 9
  .subscribe(console.log);

Upvotes: 2

Barremian
Barremian

Reputation: 31105

You could try to use Rxjs forkJoin to combine multiple observables and map the response to your requirement (using spread operator). Try the following

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

forkJoin({
  incident: incidents$,
  otherIncident: otherIncidents$,
})
.pipe(
  map(response => ([...response.incident, ...response.otherIncident]))
)
.subscribe(
  response => { // handle reponse },
  error => { // handle error }
);

RxJS forkJoin emits the last emitted value when all the observables complete.

Upvotes: 2

Edward
Edward

Reputation: 1126

you can

  • use forkjoin to wait for both observables to return
  • then use switchMap to change the result
  • in the switchMap you can manipulate the arrays. in this case we use Array.concat() to generate a new array that combines the output of the two observables

    forJoin({ incident: this.incidents$, otherIncident: this.otherIncidents$ }) .pipe( switchMap ( response => response.incident.concat(response.otherIncident)) ).subscribe( response => {//do something}, error => {//handle error} );

Upvotes: 1

Ron Rofe
Ron Rofe

Reputation: 796

You have couple of options:

  1. zip function: "After all observables emit, emit values as an array"
zip(this.incidents$, this.otherIncidents$).subscribe(...);
  1. withLatestFrom operator: "Also provide the last value from another observable"
this.incidents$
   .pipe(
      withLatestFrom(this.otherIncident$),
   )
   .subscribe(...);
  1. combineLatest function (very similar to zip) "When any observable emits a value, emit the last emitted value from each"
combineLatest(this.incidents$, this.otherIncidents$).subscribe(...);

The three of them emits an array of both of the observable.

Upvotes: 1

Related Questions