0

I have an array of objects that looks like this:

[ { firstName: 'Mike', lastName: 'Jones' },
  { firstName: 'Joe', lastName: 'Smith' },
  { firstName: 'Bob', lastName: 'Johnson' } ]

I need to pass that array to a function that's going to add a "middleName" field to each object, and a value for middleName. The function gets the middle name by making an asynchronous http.get request in Node. And therein lies the problem. I can't make this work no matter how I try.

Previously someone suggested a loop like this:

array.forEach(function (obj) {
        GetMiddleName(obj, function (person) {
            obj.MiddleName = person;
        });
    });

But that doesn't work due to the async nature of the get being called in the GetMiddleName function. Can anyone show me a short, simple function that will do what I need?

5
  • 2
    That should work fine. (Unless your problem is knowing when everything in the loop is finished) Commented Jan 17, 2020 at 11:33
  • @Quentin it doesn't work because when the loop is done running the array is untouched. Obviously I need the array to contain the new data when the loop is done. Commented Jan 17, 2020 at 11:35
  • Can you add GetMiddleName's implementation as well to the code? Commented Jan 17, 2020 at 11:36
  • Does GetMiddleName have any chance of throwing? It's quite odd for a callback API not to accept a possible error parameter Commented Jan 17, 2020 at 11:36
  • You can refer my blog Commented Jan 18, 2020 at 15:28

4 Answers 4

1

Make an array of Promises, call Promise.all on that array, and then insert the middle name to each:

const getMiddleNameProm = obj => new Promise((resolve) => {
  GetMiddleName(obj, resolve);
});
Promise.all(arr.map(getMiddleNameProm))
  .then((middleNames) => {
    for (let i = 0; i < middleNames.length; i++) {
      arr[i].MiddleName = middleNames[i];
    }
    // do stuff with populated arr here
  });
});

Sign up to request clarification or add additional context in comments.

Comments

0

This should work

let arrData = [ { firstName: 'Mike', lastName: 'Jones' },
  { firstName: 'Joe', lastName: 'Smith' },
  { firstName: 'Bob', lastName: 'Johnson' } ];

  function getMiddleName(arr){
    arr.forEach(ar => {
        //this will be your async request that gets the usrename
        asynRequest.then(person => {
        arr.MiddleName = person;
      });
    });
  }

 getMiddleName(arrData);`

Comments

0

You could use the async package to handle asynchronous iterations by using the async framework.

Using async.eachOf without callback function (returns promise). Note: available from version 3.x.

Returns:
a promise, if a callback is omitted

Type: Promise

const async = require('async');

let items = [
    { firstName: 'Mike', lastName: 'Jones' },
    { firstName: 'Joe', lastName: 'Smith' },
    { firstName: 'Bob', lastName: 'Johnson' }
];

async.eachOf(items, (item, index, callback) => {
    GetMiddleName(item, function (person) {
        item.MiddleName = person;
    })
      .then(result => {

          console.log('this is result:', result);
          callback();
      });
})
.then(() => {
   console.log('All items updated');
});

Or you can handle it with callback function like this:

async.eachOf(items, (item, index, callback) => {
    GetMiddleName(item, function (person) {
        item.MiddleName = person;
    })
      .then(result => {

          console.log('this is result:', result);
          callback();
      });
},
  (err) => {
    if (err)
        throw new Error(err);
    else
        console.log('All items updated');
  });

Comments

0

You need to create an array of promises and then resolve them. I think some of the answers here are correct but this is cleaner and easier to understand, especially if you are new to promises.

let promises = [];

array.forEach(function (item) {
  let promise = new Promise(function (resolve) {
    GetMiddleName(obj, function (person) {
        obj.MiddleName = person;
        resolve();
    });
  });

  promises.push(promise);
});

Promise.all(promises).then(function () {
  // Do something after all values/promises have been resolved
  // If not just leave it at Promise.all(promises)
});

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.