2

I have a function where I want to finish the first this.findLocation() on every loop before returning the jsonObject. The problem is when the function returns the jsonObject, some of the findlocation still not finished loop.

This is the code for the function:

generate (item) {
  let jsonObj = {}
  jsonObj.lookup = this.id
  this.fields.forEach(field => {
      if (field.prop === 'API') {
        this.findLocation(item, field).then(function (value) {
          let location = value
          if (location) jsonObj[field.prop] = location.id
        })
      } else {
        jsonObj[field.prop] = item[field.header]
      }
  })
  return jsonObj
}

Any help would be appreciate.

kit
  • 1,166
  • 5
  • 16
  • 23
Joseph Move
  • 69
  • 1
  • 9
  • From the duplicate post, [this answer](https://stackoverflow.com/a/43766002/283366) shows how to use `Promise.all` to work with a collection of asynchronous calls. – Phil Nov 21 '18 at 04:28

1 Answers1

5

You need to use Promise.all to wait for every asynchronous operation to complete:

generate (item) {
  const obj = { lookup: this.id };
  const proms = this.fields.map((field) => {
    if (field.prop === 'API') {
      // Make sure to *return* the `Promise`:
      return this.findLocation(item, field).then((value) => {
        if (value) obj[field.prop] = value.id
      })
    } else {
      obj[field.prop] = item[field.header]
    }
  });
  return Promise.all(proms)
    .then(() => obj);
}

Note that, when using .map like this, only some of the items in the array will be Promises, but that's fine - the Promise.all will simply only wait for the promises in the array to resolve. Non-promises in the array (including undefined values) will simply be ignored.

Also, as always, There's no such thing as a "JSON Object" - if you have an object or array, then you have an object or array, full stop. JSON format is a method of representing an object in a string, like const myJSON = '{"foo":"bar"}'. If there are no strings, serialization, or deserialization involved, then JSON is not involved either.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320