Pritesh Mahajan Pritesh Mahajan - 3 months ago 17
Node.js Question

wait for function and then console result

I want to wait for my functions like fetching all result first, then consoling my result.

exports.listofAllFeaturedProd = (req, res) => {

Product.find({is_featured:'1'},function(error,fetchallFeatProds)
{

var allProducts = new Array();
var pp = 0;
var products = new Array();
for (var ProductId in fetchallFeatProds)
{
var pArr = [];
pArr['_id'] = fetchallFeatProds[ProductId]._id;
pArr['name'] = fetchallFeatProds[ProductId].name;
pArr['sku'] = fetchallFeatProds[ProductId].sku;
pArr['description'] = fetchallFeatProds[ProductId].description;
pArr['price'] = fetchallFeatProds[ProductId].price;
pArr['large_image'] = fetchingImage(fetchallFeatProds[ProductId]._id);
pArr['brand'] = fetchingBrand(fetchallFeatProds[ProductId].brand_id);

console.log('#################### IMAGE ####################');
console.log(pArr);
pp++;
}
console.log(products);

});

};


function fetchingImage(pid)
{
ProductImage.findOne({product_id:pid},function(error,fetchallFeatProdsImgs)
{
console.log(fetchallFeatProdsImgs.large_image);
return fetchallFeatProdsImgs.large_image;
});
}

function fetchingBrand(bid)
{
Brand.findOne({_id:bid},function(error,fetchAllBrands)
{
console.log(fetchAllBrands);
return fetchAllBrands;

});
}


node not wait for functions and console undefined after that console my function result. how i stop my code for fetching first result then console all data in array.

Output for
console.log(pArr);


[ _id: 57bd996ebf8c930b2bcc06a1,
name: 'New Product',
sku: 'New-Product',
description: 'New Product',
price: 'test',
large_image: undefined,
brand: undefined ]


After that added console inside functions which gave results as below:

Output for
fetchingImage


images/12.png


Output for
fetchingBrand


{ user_id: '57b42b571fc35e49162de413',
brand_name: '10 Fork ',
brand_logo: 'uploads/brands_logo/1472027911329_5.png',
brand_desc: '10 Fork',
_id: 57bd5ce6cebed2a3189cedcf,
__v: 0 }


Desired output is:

[ _id: 57bd996ebf8c930b2bcc06a1,
name: 'New Product',
sku: 'New-Product',
description: 'New Product',
price: 'test',
large_image: images/12.png,
brand: { user_id: '57b42b571fc35e49162de413',
brand_name: '10 Fork ',
brand_logo: 'uploads/brands_logo/1472027911329_5.png',
brand_desc: '10 Fork',
_id: 57bd5ce6cebed2a3189cedcf,
__v: 0 } ]

Answer

Try below code:

var temp = [], 
     async = require('async');

async.eachSeries(fetchallFeatProds, function(ProductId, callback)
{
   pArr['_id']         = ProductId._id;
   pArr['name']        = ProductId.name;
   pArr['sku']         = ProductId.sku;
   pArr['description'] = ProductId.description;
   pArr['price']       = ProductId.price;
   pArr['large_image'] = fetchingImage(ProductId._id);
   pArr['brand']       = fetchingBrand(ProductId.brand_id);

   temp.push(pArr);
   callback(null);
}, function(err){
    console.log(temp); //This should give you desired result
});

If it is not working still, try using callbackfor the functions fetchingImage and fetchingBrand. Or you may try using async.parallel as well inside eachSeries.

EDIT:-

async-eachseries

Change your functions with callback.

function fetchingImage(pid, callback)
{
    ProductImage.findOne({product_id:pid},function(error,fetchallFeatProdsImgs)
   {
      console.log(fetchallFeatProdsImgs.large_image);
     callback(error,fetchallFeatProdsImgs.large_image);
   });
}

function fetchingBrand(bid, callback)
{
    Brand.findOne({_id:bid},function(error,fetchAllBrands)
    { 
       console.log(fetchAllBrands);
       calback(error,fetchAllBrands);
   });
}

Use async.parallel so that it will wait till both the functions are done. Then push into temp array. Doc to refer

async.eachSeries(fetchallFeatProds, function(ProductId, callback)
{
   var pArr  = {};
   pArr['_id']         = ProductId._id;
   pArr['name']        = ProductId.name;
   pArr['sku']         = ProductId.sku;
   pArr['description'] = ProductId.description;
   pArr['price']       = ProductId.price;
   async.parallel([
     function(callback)
     {
          fetchingImage(ProductId._id, function(err, res){
         pArr['large_image'] = res;
         callback(err); //Forgot to add
      });
   },
    function(callback)
   {
      fetchingBrand(ProductId.brand_id,function(err, res){
         pArr['brand'] = res;
         callback(err); //Forgot to add
      });
   },
], function(err){

   console.log(pArr); //Edit
   temp.push(pArr);
   callback(err); 
})
  }, function(err){
    console.log(temp); //This should give you desired result
    callback(err);
});