0

I want to extend an response in a loopback4 controller method (TypeScript). I already have an array of objects loaded from database, but each of these objects has to be extended by additional asynchronously loaded data. How do I have to build the forEach/ map method call?

The array looks like this (simplified): [{'ID':1},{'ID':2}]

For each of these objects i want to call a method async getData(record: Record): Promise<Property[]>

As far as i understand, i need to make something like this:

async fetchData()
{
   const records = [{'ID':1},{'ID':2}];
   // code...

   records.forEach((record, index) => {
      records[index].Properties = getData(record);
   });

   // here i need all promises resolved

   return records;
}   

The result is, that i have an array with pending Promises. What do i have to do, to get all of them resolved before returning the array? I found some code snippets using .map() and/or Promise.all(), but did not found my solution in these examples. Maybe because of lack of knowledge but at the moment i am stuck.

MIB
  • 337
  • 2
  • 15

2 Answers2

1

You can try this:

async fetchData()
{
   const records = [{'ID':1},{'ID':2}];
   // code...

   const promises = records.map(async (record, index) => {
      records[index].Properties = await getData(record);
   });

   // here i need all promises resolved
   await Promise.all(promises);
   return records;
}   
tano
  • 2,657
  • 1
  • 15
  • 16
  • Thank you for this solution. I had to add `await` before the `getData(record)` call, but after that i have my expected result!! – MIB Jul 23 '19 at 11:21
0

You can do this with npm async module like following:-

async fetchData()
{
   const records = [{'ID':1},{'ID':2}];
   // code...

    async.mapLimit(records, 1, function(item, cbk) {
        let Properties = getData(item);

        cbk(null, Properties);
    }, function(err, res) {
        // you will get all promises resolved here
    }); 



   // here i need all promises resolved

   return records;
} 

In Promises style:-

async.mapLimit(files, 10, async file => { // <- no callback!
    const text = await util.promisify(fs.readFile)(dir + file, 'utf8')
    const body = JSON.parse(text) // <- a parse error here will be caught automatically
    if (!(await checkValidity(body))) {
        throw new Error(`${file} has invalid contents`) // <- this error will also be caught
    }
    return body // <- return a value!
}, (err, contents) => {
    if (err) throw err
    console.log(contents)
})
Manish Balodia
  • 1,863
  • 2
  • 23
  • 37