0

I am trying to get results from a series of queries on mongodb using async method but unfortunately the object that I generate is undefined outside the async function scope.

      let dataObject = {
         prop1: 1,
         prop2: 2
         ....
      };

      let result = {};

      _.each(dataObject, async function (val, key) {

        let query = [
          {
            $match: {
              x:1
              ....
            }
          }
        ];

        let = MyModel.aggregate(query);
        let data = await q.exec();

          if (data.length > 0) {
            result[key] = data[0].myProp;
            console.log(result); // I can see result here
          }
       });

       console.log('====>>', result); // Here the result is undefined

What I am missing?

1
  • I've checked the code multiple times :/ maybe is because of the async / await scope?
    – s4f3r71
    Commented Jan 25, 2021 at 9:58

2 Answers 2

1

for this issue you can create a promise function for example getData, dataObject as input argument and the function return result like this :

let async = require('async');
let q = require('q');

const getData = async (dataObject)=>{
  let defer =q.defer();
  let result = []
  input = Object.keys(dataObject)
  async.eachSeries(input , async(key)=>{
    try {
      let query = [
        {
          $match: {
            x:1
            ....
          }
        }
      ];
      let data = await MyModel.aggregate(query).lean();
      if (data.length > 0) {
        result[key] = data[0].myProp;
        console.log(result);
      }
    } catch (error) {
      console.log(error)
    }
  },()=>{
    console.log("finish process")
    defer.resolve(result)// return final data
  })
  return defer.promise
}

in main function call this function(getData) like this :

const mainFunctio = async()=>{
  dataObject
  console.log(start)
  result  = await getData(dataObject)
  console.log(result)
}
6
  • I've tried your solution but using this method I get the value of the property (eg. in prop1 i get 1 instead on the property name) and I need both key value to create the final object. Thanks.
    – s4f3r71
    Commented Jan 25, 2021 at 14:01
  • I've Updated my answer, check it, input = Object.keys(dataObject) Commented Jan 25, 2021 at 14:15
  • I've updated the code accordingly but again the result object is undefined. I've also tried to populate a property manually inside the loop and the result is always the empty array defined at the beginning. I am so confused... Thanks
    – s4f3r71
    Commented Jan 25, 2021 at 15:08
  • I edited my answer, run it, and show me the result of output Commented Jan 25, 2021 at 15:13
  • I did try that as well: result: {} output: [] finish thanks
    – s4f3r71
    Commented Jan 25, 2021 at 15:28
0

As a reference I am posting a solution that I found and looks very simple. Instead of using _.each operator I tried to use a simple for loop and also removed the exec() (as suggested by Mohammad) and it worked as expected:

  let dataObject = {
     prop1: 1,
     prop2: 2
     ....
  };

  let result = {};
  let allKeys = Object.keys(dataObject)
   for (key of allKeys) { {

    let query = [
      {
        $match: {
          x:1
          ....
        }
      }
    ];

    let data = MyModel.aggregate(query);

      if (data.length > 0) {
        result[key] = data[0].myProp;
      }
   });

   console.log('====>>', result); // works fine!

Not the answer you're looking for? Browse other questions tagged or ask your own question.