0

This is in the context of a node express route. I receive a get request with a query param that is a list of IDs. Now I need to make a call-out for each ID and store the result of the callout in an array or object. Each element of the first array (containing the IDs) need to be mapped to its corresponding result from the call-out. I don't have a way to modify the endpoint that I'm hitting from this route so I have to make single calls for each ID. I've done some research and so far I have a mixture of code and sudo code like this:

const ids = req.query.ids;
const idMembers = Promise.all(ids.map(async id => { 
  // here I'd like to create a single object or associative array
  [ id: await callout(id); ]
}));

When all promises resolved I need the final result of idMembers to be like: (The response will be an object with nested arrays and objects I've just simplified it for this post but I need to grab that from the res.payload)

{
  '211405': { name: 'name1', email: '[email protected]' },
  '441120': { name: 'name2', email: '[email protected]' },
  '105020': { name: 'name3', email: '[email protected]' }
}

Oh and of course I need to handle the callout and the promise failures and that's when my lack of experience with javascript becomes a real issue. I appreciate your help in advance!!

Some extra thought I'm having is that I'd have to map the results of the resolved promises to their id and then in a separate iteration I can then create my final array/object that maps the ids to the actual payloads that contain the object. This is still not answering any of my questions though. I'm just trying to provide as much information as I've gathered and thought of.

1 Answer 1

1

Promise.all returns an array of results (one item per each promise).

Having this temporary structure it is possible to build the needed object.

const arrayOfMembers = Promise.all(ids.map(async id => { 
  // ...
  return { id, value: await callout(id) } // short syntax for { id: id, value: ... } (see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer)
}));
// arrayOfMembers = [
//  { id: 211405, value: { name: 'name1', email: '[email protected]' } },
// ...
// ]

In pure JS it can be done with for loop or .forEach() call to iterate:

const res = {};
arrayOfMembers.forEach(el => {
  const { id, value } = el;
  res[el] = value;
});

or by using a single reduce() call

const res = arrayOfMembers.reduce((accumulator, el) => {
   const { id, value } = el;
   return { ...accumulator, [id]: value };
}, {});

in both cases res will be:

// res = {
//   '211405': { name: 'name1', email: '[email protected]' },
// ...
// }

P.S.

There is a handy library called lodash. It has tons of small methods for data manipulation.

For example, _.fromPairs() can build an object from [[key1, value1], [key2, value2]] pairs.

As you mentioned you have lodash, so I think the following should work:

const arrayOfKeyValuePairs = Promise.all(ids.map(async id => { 
  // ...
  return [ id, await callout(id) ] // array here so it matches what fromPairs needs
}));
const res = _.fromPairs(arrayOfKeyValuePairs);
Sign up to request clarification or add additional context in comments.

7 Comments

Man this is awesome. Thanks for the quick response. I do have access to lodash so thanks so much for that suggestion. My only question from your answer is in your first snippet, return { id, value: await callout(id) }, how does this result in { id: 211405 ... , I'm just confused about the "id" assignment part. Thanks!!
Just to confirm that I understand it all correctly, I'll need two separate loops to create the final result right?
Updated about id. I'm using short syntax here for { id: id}, see docs developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
You rock man! I wish I could upvote more than once, much appreciate your help!!
Yes, first loop is inside Promise.all(...here...), which converts ids to promises. Second loop is arrayOfMembers.forEach.
|

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.