0

I want to create a array with like this

[{
"item":"item1",
"subitem":[{"subitem1","subitem2"}]
},{
"item":"item2",
"subitem":[{"subitem3","subitem4"}]
}]

I am connected to mysql RDS and trying to executes some queries. My code for express js with serverless framework is as follows:

app.get('/modules/all', function async(req, res) {
    let data = await run();
    res.send(data);
})


async function run() {
    return new Promise((resolve, reject) => {
        con.query('SELECT `module_name` FROM `module_master` GROUP BY `module_name`', (err, rowsmod) => {
            if (err) throw reject(err);
            var rowdata = [];
            for (var j = 0; j < rowsmod.length; j++) {
                var modulenames = rowsmod[j].module_name;
                let resModule = await getSubmodule(modulenames);
                console.log(resModule);
                resModule = JSON.parse(resModule);
                rowdata.push({
                    "module": modulenames,
                    "submodule": resModule
                });
            }
            resolve(rowdata);
        })
    });
}


async function getSubmodule(modulenames) {
    return new Promise((resolve, reject) => {
        con.query('SELECT * FROM `module_master` WHERE `module_name` = ?', [modulenames], (err, rows) => {
            if (err) throw reject(err);
            resolve(rows);
        });
    })
};

Error obtained as await is only valid in async function, but the async is already defined. Why am I getting this issue?

E: \serverless\ index.js: 122
let data = await run(); 
         ^ ^ ^ ^ ^

SyntaxError: await is only valid in async function
at compileFunction( < anonymous > )
at wrapSafe(internal / modules / cjs / loader.js: 1053: 16)
at Module._compile(internal / modules / cjs / loader.js: 1101: 27)
at Object.Module._extensions..js(internal / modules / cjs / loader.js: 1157: 10)
at Module.load(internal / modules / cjs / loader.js: 985: 32)
at Function.Module._load(internal / modules / cjs / loader.js: 878: 14)
at Module.require(internal / modules / cjs / loader.js: 1025: 19)
at require(internal / modules / cjs / helpers.js: 72: 18)
at E: \serverless\ express\ aipersonalization\ node_modules\ serverless - offline\ dist\ lambda\ handler - runner\ in -process - runner\ InProcessRunner.js: 145: 133
at processTicksAndRejections(internal / process / task_queues.js: 97: 5)
at InProcessRunner.run(E: \serverless\ express\ aipersonalization\ node_modules\ serverless - offline\ dist\ lambda\ handler - runner\ in -process - runner\ InProcessRunner.js: 145: 9)
halfer
  • 19,824
  • 17
  • 99
  • 186
  • 3
    `function async(req, res)` -> `async function(req, res)` – VLAZ Nov 27 '20 at 08:56
  • 1
    Probably related: [Why are await and async valid variable names?](https://stackoverflow.com/q/55934490) | [Why can the `async` and `await` keywords be assigned to?](https://stackoverflow.com/q/56869954) – VLAZ Nov 27 '20 at 08:57
  • This works but again stuck in this part ----> let resModule = await getSubmodule(modulenames); – Roni Modak Nov 27 '20 at 09:02
  • offline: Failure: await is only valid in async function E:\serverless\express\aipersonalization\index.js:134 let resModule = await getSubmodule(modulenames); ^^^^^ SyntaxError: await is only valid in async function – Roni Modak Nov 27 '20 at 09:22
  • also use async wrapper for `await getSubmodule(modulenames);` like `return new Promise(async (resolve, reject) => {})` – Ameer Hamza Nov 27 '20 at 09:37
  • 1
    @AmeerHamza [don't use `async` executors for promises](https://stackoverflow.com/questions/43036229/is-it-an-anti-pattern-to-use-async-await-inside-of-a-new-promise-constructor) – VLAZ Nov 27 '20 at 09:40
  • not working @AmeerHamza – Roni Modak Nov 27 '20 at 09:51

1 Answers1

1

You should promisify only the con.query call in a separate method, and not mix the handling of the rowsmod into the new Promise constructor as well:

function query(con, ...args) {
    return new Promise((resolve, reject) => {
        con.query(...args, (err, rows) => {
            if (err) reject(err); // no `throw` here!
            else resolve(rows);
        });
    });
}

Then, you can use that helper function in your business logic and await its results:

function getSubmodule(modulenames) {
    return query(con, 'SELECT * FROM `module_master` WHERE `module_name` = ?', [modulenames]);
}

async function run() {
    const rowsmod = await query(con, 'SELECT `module_name` FROM `module_master` GROUP BY `module_name`')
    const rowdata = [];
    for (var j = 0; j < rowsmod.length; j++) {
        const modulename = rowsmod[j].module_name;
        let resModule = await getSubmodule(modulename);
        rowdata.push({
            "module": modulename,
            "submodule": resModule,
        });
    }
    return rowdata;
}

app.get('/modules/all', function (req, res) {
    run().then(data => {
        res.send(data);
    }, err => {
        res.status(500).send('Sorry.');
    });
})
Bergi
  • 630,263
  • 148
  • 957
  • 1,375