Home > Software design >  How to left join two json array based on common id using RxJS
How to left join two json array based on common id using RxJS

Time:12-18

Need help on a problem with Rxjs join. I have two observables with common id, I want to perform join to show records from both objects based on id.

    let emp = of([
      { id: 1, name: 'aa', age: 20 },
      { id: 2, name: 'bb', age: 21 },
      { id: 3, name: 'cc', age: 22 },
      { id: 4, name: 'dd', age: 23 }
    ]);
   let details = of([
      { id: 1, address: 'ee' },
      { id: 1, address: 'ff' },
      { id: 2, address: 'gg' },
      { id: 2, address: 'hh' }
    ]);

I need the join like this:

[
 {id: 1, name: 'aa', age: 20, details: [{address: 'ee'},{address: 'ff'}] },
 {id: 2, name: 'bb', age: 21, details: [{address: 'gg'},{address: 'hh'}] },
 {id: 3, name: 'cc', age: 22, details: undefined },
 {id: 4, name: 'dd', age: 23, details: undefined },
]

I have tried like this:

  forkJoin([emp, details]).pipe(
      map(([_emp, _details]) =>
        _emp.map((item) => {
          return ( {
            ...item,
            details: _details.find((item1) => {
              return item1.id === item.id
            })
          })
        })
      )
    ).subscribe(console.log)

I got the result:

[
 {id: 1, name: 'aa', age: 20, details: [{address: 'ee'}] }, // {address: 'ff'} missing
 {id: 2, name: 'bb', age: 21, details: [{address: 'gg'}] }, // {address: 'hh'} missing
 {id: 3, name: 'cc', age: 22, details: undefined },
 {id: 4, name: 'dd', age: 23, details: undefined },
]

In this result second address is missing for id 1 and 2.

Instead of [{address: 'ee'},{address: 'ff'}], I got only first match [{address: 'ee'}] for id 1.

Instead of [{address: 'gg'},{address: 'hh'}], I got only first match [{address: 'gg'}] for id 2.

Please help me to accomplish the desired result

CodePudding user response:

I think you should use filter() instead of find(). The find() operator returns only the first match.

  forkJoin([emp, details]).pipe(
      map(([_emp, _details]) =>
        _emp.map((item) => {
          return ({
            ...item,
            // This is the line you have to modify:
            details: _details.filter((item1) => item1.id === item.id)
          })
        })
      )
    ).subscribe(console.log)

  • Related