0

I'm newbie to RxJs. I could not find how to do it. I have a large number of nested http requests in my master data. And I want to get all the http requests and combine them all in my main stream.

My example main stream data as:

[
    {
        id: '123',
        name: 'nameVal1',
        salary: [
            { href: 'http://example.com/salary/1' },
            { href: 'http://example.com/salary/2' }
        ],
        address: {
            href: 'http:/example.com/address'
        }
    },

    {
        id: '456',
        name: 'nameVal2',
        salary: {
            href: 'http://example.com/salary/1'
        },
        address: {
            href: 'http:/example.com/address'
        }
    }
];

Example salary object:

{
    salary: '1000€',
    month: 2
}

Example address object:

{
    country: 'UK',
    city: 'London',
    postalCode: '123'
}

My main stream is array of objects like above and after get the main stream, I want to get all nested data and combine them all the main stream like that:

[
{
    id: '123',
    name: 'nameVal1',
    salary: [
        {
            salary: '1000€',
            month: 2
        },
        {
            salary: '500€',
            month: 3
        }
    ],
    address: {
        country: 'UK',
        city: 'London',
        postalCode: '123'
    }
},

{
    id: '456',
    name: 'nameVal2',
    salary: [
        {
            salary: '2000€',
            month: 3
        }
    ],
    address: {
        country: 'UK',
        city: 'London',
        postalCode: '456'
    }
}
];


this.service.mainHttpReq().pipe(
    map(users => {
        users.salary.forEach(salaryItem => { 
            return fetch(salaryItem.href); 
        });
        

    })
).subscribe(usersData => {
   console.log('Users Data :', usersData);
});

2 Answers 2

1

Use forkJoin to fetch data in parallel.

mainStream.pipe(
  // fetch data for every person
  switchMap(persons => forkJoin(
    persons.map(person => getPersonData(person))
  ))
);

// get data for a single person
function getPersonData(person): Observable<any> {
  // the salary data as an observable
  const salaryData = forkJoin(person.salary.map(({ href }) => getSalaryData(href));
  // the address data as an observable
  const addressData = getAddressData(person.address.href);
  // combine salary and address data
  return forkJoin(salaryData, addressData).pipe(
    // map salary and address data to a person object with this data
    map(([ salary, address ]) => ({ ...person, salary, address }))
  );
}
Sign up to request clarification or add additional context in comments.

Comments

1

The right solution might depend on whether you want to fetch salaries concurrently or not but you could do it for example like this:

this.service.mainHttpReq().pipe(
  concatAll(), // Unwrap the users array into individual `next` values representing each user.
  concatMap(user => // Process users in sequnece one by one.
    forkJoin( // Fetch all salaries and address for this user in parallel.
      forkJoin(user.salary.map(salary => fetch(salaryItem.href))), 
      fetch(user.address),
    ).pipe(
      map(([salaries, address]) => { // Update the original user object.
        user.salary = salaries; 
        user.address = address;
        return user;
      }),
    ),
  ),
  toArray(), // Collect into a one array of users.
).subscribe(...);

I didn't test the code above but I hove you'll get how it works.

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.