0

Hello I am having the following problem with my API.

I am calling a function in my models from my service like so,

async getAccounts(/*offset = 0, limit = 500,*/ res) {
     try {
              let offset = 0;
              let limit = 500;
              let result = await this.model.getAllAccounts(offset, limit);
              console.log(result, "Debugger 3");
              return res.status(200).json(result);
     } catch (error) {
              logger.error('AccountsService::getAccounts', 39);
              logger.error(error);
              return errorHandler(error, res);
     }
}

And the function in my models class looks something like this.

async getAllAccounts(offset, limit) {
    // Need  to add offset and limit parameters //done
    console.log("URL",url);
    MongoClient.connect(url, function(err, db) {
      if (err) throw err;
      logger.log('Query Accounts');
      const dbo = db.db("DB_NAME");
      dbo.collection('accounts').find({}).skip(offset).limit(limit).toArray(function(err, result) {
            if (err) throw err;
            db.close();
            logger.log("Debugger 2xxx: ",result);
            return result;
          });
        });
      }

The problem I am having is that before Debugger 3's output comes before Debugger 2's output.

I think I need to await the result being returned from MongoDB but not sure how to do it. Could anyone please guide me?

coder123
  • 841
  • 1
  • 7
  • 19

3 Answers3

1

await needs a promise for async to work. Currently, since your function returns undefined (as all functions without an explicit return), await is getting a promise of undefined, which is immediately resolved, and no waiting is necessary. On the other hand, the dbo uses a callback, not a promise; you cannot return a result from an asynchronous callback.

You should do something like this (not tested though):

async getAllAccounts(offset, limit) {
  // Need  to add offset and limit parameters //done
  console.log("URL",url);
  return new Promise(function(resolve, reject) {
      MongoClient.connect(url, function(err, db) {
          if (err) throw err;
          logger.log('Query Accounts');
          const dbo = db.db("DB_NAME");
          dbo.collection('accounts').find({}).skip(offset).limit(limit).toArray(function(err, result) {
              if (err) throw err;
              db.close();
              logger.log("Debugger 2xxx: ",result);
              resolve(result);
          });
      });
  });
}
Amadan
  • 191,408
  • 23
  • 240
  • 301
1

If you're using the mongo db driver following versions 2.x, ie all version 2.x, 3.x, MongoClient.connect return a promise if no callback is passed as argument. So you can do the next thing :

async getAllAccounts(offset, limit) {
  // Need  to add offset and limit parameters //done
  try {
    console.log("URL", url);
    let db = await MongoClient.connect(url);
    logger.log("Query Accounts");
    const dbo = db.db("DB_NAME");
    const result = await dbo
      .collection("accounts")
      .find({})
      .skip(offset)
      .limit(limit)
      .toArray();
    db.close();
    logger.log("Debugger 2xxx: ", result);
    return result;
  } catch (e) {
    throw e;
  }
}
ocheriaf
  • 580
  • 3
  • 11
  • Going through my stackoverflow. Yup. This should be the solution, but I'm goin to keep the other one as the solution as a lot of new developers struggle with returning promises :smile: – coder123 Nov 14 '21 at 16:41
0

The reason why the getAllAccounts function call didn't await. Await will only work for a function that returns a promise. Here getAllAccounts doesn't return a promise, so wrap the method with a promise.

modul.exports.getAllAccounts = (offset, limit)=> {
    // Need  to add offset and limit parameters //done
   return new Promise((resolve,reject)=>{

    console.log("URL",url);
    MongoClient.connect(url, function(err, db) {
      if (err){ 
      reject(err);
      return; 
          }
      logger.log('Query Accounts');
      const dbo = db.db("DB_NAME");
      dbo.collection('accounts').find({}).skip(offset).limit(limit).toArray(function(err, result) {
            if (err){
                  reject(err);
                  return; 
               }
            db.close();
            logger.log("Debugger 2xxx: ",result);
            resolve(result);
          });
        });

});

      }
ArUn
  • 1,317
  • 2
  • 23
  • 39