0

Currently we are storing short strings as keys.

These keys correspond to long values which are labels.

I am trying to update the corresponding long value for the key.

But the console.log(record) always executes first and then the inner log statement executes which is not is desired. It always sends the unmodified record to the getRadioValues function caller.

I want to return the record after the corresponding key is updated.

export const getRadioValues = (record: IRecordInput) => {
    const singleSelectKeys = ['Race', 'DeathWas', 'MannerOfDeath'];
    singleSelectKeys.forEach(async key => {
        if (record[key]) {
            const dropDownOption = await DropDownOptions.find({ where: { id: record[key] }}) as IPDFSelect;
            record[key] = dropDownOption.dataValues.Text;
            console.log(record[key]);
        }
    });
    console.log(record);
    return record;
};
Gaurav Shah
  • 175
  • 4
  • 15

1 Answers1

2

Your forEach is using an async function which means that the loop probably finishes before any of the promises it created do. To fix this, you need to get the result of your promises and wait on them. However, this means the enclosing function must itself be async, which may or may not be acceptable for your actual use case.

export const getRadioValues = async (record: IRecordInput) => {
    const singleSelectKeys = ['Race', 'DeathWas', 'MannerOfDeath'];
    await Promise.all(singleSelectKeys.map(async key => {
        if (record[key]) {
            const dropDownOption = await DropDownOptions.find({ where: { id: record[key] }}) as IPDFSelect;
            record[key] = dropDownOption.dataValues.Text;
            console.log(record[key]);
        }
    }));
    console.log(record);
    return record;
};
CRice
  • 29,968
  • 4
  • 57
  • 70
  • `which may or may not be acceptable for your actual use case.` - acceptability is irrelevant. result returned by `getRadioValues` is asynchronous, it must be used as an asynchronous function (doesn't have to be `async` though if you return a promise) – Jaromanda X Nov 21 '17 at 22:15
  • Initially I had tried using the same code as you suggested except the Promise.all function. Wouldn't async await resolve the promises itself? – Gaurav Shah Nov 21 '17 at 22:16
  • yes, inside the callback – Jaromanda X Nov 21 '17 at 22:20
  • @GauravShah I'm uncertain what you mean? The `await Promise.all` is what ensures that all the promises have resolved before it moves to the next line. You can't await an array (well you can, but it doesn't do anything), so the `Promise.all` is definitely a necessary part of this. I might have misunderstood though, so if you can clarify, I'll provide a better answer. – CRice Nov 21 '17 at 22:23
  • @CRice: I think my understanding of Async/Await was not clear. Await waits till the Promise is resolved and then executes the next statement. I thought that it Await resolves the promise itself and we don't have to use Promise.all or Promise.resolve statement. – Gaurav Shah Nov 21 '17 at 22:27