-3

I have the following async javascript code which calls the async method findDevices of the class Devices, in another file. It's an async method since I'm doing a mongo find in collection IDevices within that method. The code is below:

let devices = await Devices.findDevices()

The class is below:

module.exports = class Devices{
    static async findDevices() {
            let devices = await IDevices.find({"Region" : {"$exists": false}})
            loggingService.getDefaultLogger().info("Devices without region: " + devices)
            return devices
        }
}

When I try to execute this code, I get the following error:

let devices = await Devices.findDevices()
              ^^^^^

SyntaxError: await is only valid in async function
    at wrapSafe (internal/modules/cjs/loader.js:979:16)
    at Module._compile (internal/modules/cjs/loader.js:1027:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
    at internal/main/run_main_module.js:17:47

I don't understand why I'm getting this error since findDevices is an async method. How can I resolve this error and how should I be calling this method. Is there another approach I'm not considering and don't I need the method to be asyn since I'm doing a mongo find with mongo collection IDevices?

Would wrapping it in an async function look like this:

async function regionBackfill() {
    let devices = await Devices.findDevices()
    if(devices){
        devices.forEach(device => {
            await Device.updateRegion(device.SerialNumber)
        });
    }
}

If so, would I just call regionBackfill() ? How would I call it? If I just call it as: regionBackfill(); I get the same error

ENV
  • 877
  • 2
  • 10
  • 32
  • 1
    await is only valid in async function. Is your statement `let devices = await Devices.findDevices()` in an async function. That is the rule. Wrap it in an asyn func and call it or use then. – Tushar Shahi Jun 26 '21 at 18:33
  • The error is in `let devices = await Devices.findDevices()`, not `let devices = await IDevices.find({"Region" : {"$exists": false}})`. – programmerRaj Jun 26 '21 at 18:33
  • @TusharShahi, I've updated my question. How can I wrap it in an async function and then call it? – ENV Jun 26 '21 at 18:40
  • Does this answer your question? [How and when to use ‘async’ and ‘await’](https://stackoverflow.com/questions/14455293/how-and-when-to-use-async-and-await) – nyedidikeke Jun 26 '21 at 18:42
  • forEach will not respect await inside it. regionBackfill() is causing an error. Don't call it with await. If you are doing that then we are back to the original problem. – Tushar Shahi Jun 26 '21 at 18:57

2 Answers2

0

async await is basically syntactic sugar over promises.

The way to use async function is:

const example = async () => {
  await otherCall();
}

Also you can do:

async function example() {
  await otherCall();
}

For your specific question, I've one suggestion to make calls parallel:

async function regionBackfill() {
    let devices = await Devices.findDevices()
    if(devices){
        Promise.all([...devices.map({SerialNumber} => Device.updateRegion(SerialNumber)])
    }
}
Shravan Dhar
  • 1,455
  • 10
  • 18
0

you tryed call the method without a async method. You may call the method thus:

Devices.findDevices().then(response => devices)