Miguel Moura
Miguel Moura

Reputation: 39394

Join two observables and remove duplicates

I am calling two service methods in Angular 9 as follows:

var u1 = this.userService.getByDepartmentId(departmentId).pipe(
  map((payload: Payload<GetByDepartmentIdModel[]>) => 
    payload.result.map((user: GetByDepartmentIdModel) => { 
      return {
        id: user.id, 
        forename: user.forename, 
        surname: user.surname 
      };
    })));

var u2 = this.userService.getByStoreId(storeId).pipe(
  map((payload: Payload<GetByStoreIdModel[]>) => 
    payload.result.map((user: GetByStoreIdModel) => { 
      return {
        id: user.id, 
        forename: user.forename, 
        surname: user.surname 
      };
    })));

The methods getByDepartmentId and getByStoreId returns an Observable<Payload<GetByDepartmentIdModel[]> and Observable<Payload<GetByStoreIdModel[]>>.

How can I join the two response, u1 and u2 and remove duplicates (compare user.id)?

Upvotes: 2

Views: 1132

Answers (2)

phip1611
phip1611

Reputation: 6140

You can use forkJoin.

const users = new Subject();
forkJoin([u1, u2]).subscribe([u1, u2] => {
    if (u1.id === u2.id) {
        users.next(u1);
    } else {
        users.next(u1);
        users.next(u2);
    }
});

And subscribe to users.

users.subscribe(user => ...);

PS: Note that forkJoin waits until both observables are completed. Perhaps you want to use combineLatest or zip instead. Learn more here: https://scotch.io/tutorials/rxjs-operators-for-dummies-forkjoin-zip-combinelatest-withlatestfrom

PS: Please don't use var. Use const or let.

Upvotes: 1

Poul Kruijt
Poul Kruijt

Reputation: 71911

Well, you first use forkJoin to combine the observables, after that you do a basic array method concat with filter, map it to the object you want, and you are done:

forkJoin([
  this.userService.getByDepartmentId(departmentId),
  this.userService.getByStoreId(storeId)
]).pipe(
  map(([ depPayload, storePayload ]) => depPayload.result.concat(storePayload.result)
    .filter(({ id }, i, arr) => arr.findIndex((subj) => subj.id === id) === i)
    .map(({ id, forename, surname }) => ({ id, forename, surname })
);

Upvotes: 3

Related Questions