0

I have declare the variable first. but if I do console.log(userinsertData) outside looping variable still not fill. what i should do for solving this problem? here my code:

var User = require('../models/user');

module.exports = {
  myaction: function(req, res, next) {
    var data = req.body,
      userinsertData = [];
    try {
      data.forEach(function(item, index) {
        var userdata = new User();
        userdata.name = item.name;
        userdata.age = item.age;
        userdata.sex = item.sex;
        userdata.save(function(err, data) {
          if (err) {
            res.send(err)
          } else {
            userinsertData.push(data);
          }
        });
      })
    } catch (e) {
      res.json({
        message: 'data not valid'
      })
    }
    console.log(userinsertData);
    res.json({
      message: 'musician created!',
      data: userinsertData
    });
  }
};
4lackof
  • 1,250
  • 14
  • 33
Riza Masta
  • 15
  • 8
  • That's because `userdata.save()` is asynchronous. It completes long after your function has already finished. So your `console.log(userinsertdata)` happens before `userdata.save()` has finished and called its callback. Put the `console.log()` in the callback function. That's where you use the result. You have another problem though because you're doing an async operation inside a loop which means all the async operations are in flight at the same time and there is no guaranteed finish order. – jfriend00 Aug 20 '16 at 04:30
  • sorry, I don't know callback function from `userdata.save()` – Riza Masta Aug 20 '16 at 04:37
  • 1
    You have to somehow know when N async operations are complete. A number of options are here: [How can I wait for set of asynchronous callback functions?](http://stackoverflow.com/questions/10004112/how-can-i-wait-for-set-of-asynchronous-callback-functions/10004137#10004137). – jfriend00 Aug 20 '16 at 04:40

2 Answers2

0
    you should solve the problem as
    async.eachSeries(data, function (info, callback) {
                   //here process your data and call callback() for next iteration

                  }, function (err) {
                    if (err) {
//this will be called after all iterations and in case of error
                    }else{
                      console.log('Well done :-!');
    //this will be called after all interations successfully
                    }

                  });

this problem you are facing is because of asynchronous nature of nodejs and async helps you to introduce blocking.

Don't forget to include async

Dinesh Agrawal
  • 326
  • 1
  • 3
  • look this method so simple, but what the purpose of `async.eachSeries`? should I declaration it first? – Riza Masta Aug 20 '16 at 05:21
  • just add async = require('async') in the begining of code. The use of async.eachSeries is to iterate over a array synchronously and call a callback function in the end of loop – Dinesh Agrawal Aug 21 '16 at 04:20
0

Use promise

var User = require('../models/user');

module.exports = {
  myaction: function(req, res, next) {
    var data = req.body,
      userinsertData = [];

    new Promise(function(resolve, reject) {
      data.forEach(function(item, index) {
        var userData = new User(item);
        userData.save(function(err, data) {
          // if error, reject
          if(err) return reject(err);
          // we have proceed all items in data, resolve it
          else if(data.length - 1 === index) return resolve(userinsertData);
          // not finished yet, keep proceeding
          else userinsertData.push(data);
       });
    }).then(function(successResult) {
      res.json({
        message: 'musician created!',
        data: successResult
      });
    }, function(errorResult) {
      res.json({
        message: 'data not valid'
      });
    });
  }
};

Use callbacks

var User = require('../models/user');

module.exports = {
  myaction: function(req, res, next) {
    var data = req.body,
      userinsertData = [];

    function saveUser(callback) {
      data.forEach(function(item, index) {
        var userData = new User(item);
        userData.save(function(err, data) {
          // if error, return callback with error
          if(err) return callback(err);
          // we have proceed all items in data, return data
          else if(data.length - 1 === index) callback(null, userinsertData);
          // not finished yet, keep proceeding
          else userinsertData.push(data);
       });
    }

    saveUser(function(err, users) {
      if(err) return res.json({message: 'data not valid'});
      res.json({
        message: 'musician created!',
        data: users
      });
    });
  }
};

This is what async package does internally

Medet Tleukabiluly
  • 11,662
  • 3
  • 34
  • 69