'async function is returning undefined in nodejs [duplicate]

This is my code

async function checksubsdetails() {
  try {
    let update_data = [];
    db_office.query(
      `SELECT arn_no,arn_id,cams_email from no_of_arn WHERE cams_email !=''`,
      async (err, arn_rows) => {
        if (err) throw err;

        for (let inx of arn_rows) {
          // console.log(inx.arn_no)
          await db_office.query(
            `SELECT arn_no from cams_subs WHERE arn_no='${inx.arn_no}'`,
            async (err, subs_rows) => {
              if (err) throw err;
              // console.log(subs_rows)
              if (subs_rows.length == 0) {
                await db_office.query(
                  `INSERT INTO cams_subs(arn_id, arn_no) values('${inx.arn_id}', '${inx.arn_no}')`,
                  (err, my_cursor) => {
                    if (err) throw err;
                    console.log(("New Data Added for Arn no -> ", inx.arn_no));
                    update_data.push(inx);
                  }
                );
              } else {
                console.log("Data Already Exists for arn no ->", inx.arn_no);
                //console.log(("New Data Added for.lo"))
                update_data.push(inx);
              }
            }
          );
        }
        return [2, update_data];
      }
    );
  } catch (err) {
    console.log(err);
    return [1, "Exception While adding Data to Cams Subs"];
  }
  
}

I am returning [2, update_data] but getting undefined for update_data.

I am not able to figure out what to do to resolve this because the further processes can only occur after getting this value.

update_data is giving result in if-else statement I have written but I want it to return the update_data array after for loop.

Please help me out in this.

Thanks



Solution 1:[1]

@jfriend00 explained the problem – here's one possible solution that uses Node.js's util.promisify function to take the db_office.query function and turn it into something that can actually be awaited upon.

Please heed the comments in the code.

async function checksubsdetails() {
  // Promisify the `db_office.query` function (depending on the library,
  // it may already have a promisified counterpart; please read the docs).
  const queryP = util.promisify(db_office.query.bind(db_office));
  const update_data = [];

  const arn_rows = await queryP(
    `SELECT arn_no, arn_id
     from no_of_arn
     WHERE cams_email !=''`,
  );
  for (let inx of arn_rows) {
    // TODO: this is susceptible to race condition attacks since multiple processes
    //       may be doing this loop simultaneously
    const subs_rows = await queryP(
      `SELECT arn_no
       from cams_subs
       WHERE arn_no = '${inx.arn_no}'`, // TODO: fix SQL injection vulnerability
    );
    if (subs_rows.length === 0) {
      await queryP(
        `INSERT INTO cams_subs(arn_id, arn_no)
         values ('${inx.arn_id}', '${inx.arn_no}')`, // TODO: fix SQL injection vulnerability
      );
      console.log("New Data Added for Arn no -> ", inx.arn_no);
    } else {
      console.log("Data Already Exists for arn no ->", inx.arn_no);
    }
    update_data.push(inx);
  }
  return update_data;
}

Solution 2:[2]

Inside function line no 4, you are calling db_office.query() without await. So this promise was not fulfilled. So, just after running the function, that promise is getting added in the asynchronous event loop and returned. You are not waiting to get the promise fulfilled. When that promise is fulfilled after the return, you are seeing the output in the console. Try with await and return your return after the promise is fulfilled

await db_office.query()
// return after every promise is fulfilled

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 AKX
Solution 2 Shohidul Bari