'Connect two observables to find name by id

I've got 2 endpoints:

users = [
 {
   id: 1,
   name: 'Mark',
   companyId: 1
 },
 {
   id: 2,
   name: 'Jack',
   companyId: 1
 },
]
companies = [
 {
   name: 'Facebook',
   id: 1
 }
]

Now, how can I build my observer to get company name in every user? So in my html i Can do for example. user.company.name

My get method now: baseUrl is localhost:3000/users

  getUsers(): Observable<IUser[]> {
    return this.http.get<IUser[]>(this.baseUrl).pipe(
      share()
    );
  }


Solution 1:[1]

Use forkJoin to get users and companies data parallelly, then map the result as required type.

forkJoin([
    this.http.get<IUser[]>(this.baseUrl + '/users'),
    this.http.get<IComapany[]>(this.baseUrl + '/comapnies')
]).pipe(map(([users, companies]) => users.map(user => 
    {
      return {
        "id": user.id,
        "name": user.name,
        "company": companies.find(x=> x.id == user.companyId)
      } 
    })
))

Example: https://stackblitz.com/edit/rxjs-wkdn3r

Solution 2:[2]

The short answer is forkJoin.

Example:

const usersObservable = this._http.get('https://example/api/users');
const companiesObservable = this._http.get('https://example/api/companies');

const usersAndCompanies = Observable.forkJoin([usersObservable, companiesObservable])
  .subscribe(
     result => return this._joinUsersAndCompanies(result) 
  );


private _joinUsersAndCompanies(result) {

  const users = result[0];
  const companies = result[1];

  return users.map(user => {

    const matchedCompany = companies.find(company => company.Id === user.companyId);
    
    return {
      ...user,
      companyName: matchedCompany!.name
    };

  });
}

This is just a draft, and I am not sure if this will compile and run properly, but I hope you get the idea.

If you need to get users and companies from the API frequently or the return data is big, you can optimize by first convert and store the const companies in a map so you can access them in a constant time bigO(1).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2