Vishnu
Vishnu

Reputation: 755

Getting empty array in nodejs

I am posting value But I am getting empty array . I know its node asynchronous problem . But I don't know how do i solve this. I have refer this following link:

How do I return the response from an asynchronous call?

But I could not able to understand . Kindly help me to understand promises and how do i use that in my code.

router.post('/inspection_list', function (req, res) {
    var id = req.body.project_id;
    console.log(id)
// res.send("ok")
    db.inspection.findOne({'_id':id},(err,response)=>{
        if(err){
            console.log("error");
        }
        else{
            console.log("Data")
            var inspection = [];
            var data = response.inspection_data;
      var f =  data.map(function (item) { 
                var fielduser = item.fielduser_id
                db.fielduser.findOne({'_id': mongoose.Types.ObjectId(fielduser)},(err,user)=>{
                    console.log(user.owner_name);
                    console.log(item.inspection_name)
                    inspection.push({inspection_name:item.inspection_name,field_user_name : user.owner_name})


                })
                });
console.log(inspection) // Here am getting empty value
           // setTimeout(function(){ console.log(inspection) }, 5000); my timeout code


        }
    })
});

Upvotes: 0

Views: 327

Answers (2)

pr0p
pr0p

Reputation: 2358

router.post('/inspection_list', async function (req, res) {
    var id = req.body.project_id;
    try{
        var response = await db.inspection.findOne({'_id':id})
        var inspection = [];
        var data = response.inspection_data;
        for ( var i = 0; i<data.length; i++){
            var item = data[i]
            var fielduser = item.fielduser_id
            var user = await db.fielduser.findOne({'_id': mongoose.Types.ObjectId(fielduser)})
            inspection.push({inspection_name:item.inspection_name,field_user_name : user.owner_name})
       }
    }
    catch(err){
        throw err
    }
})

This uses async and await, you can use it if you are using node version >=7.6

Also note the following:

router.post('/inspection_list', async function (req, res)


Handling each error seperately

router.post('/inspection_list', async function (req, res) {
    var id = req.body.project_id;
    try{
        var response = await db.inspection.findOne({'_id':id})
    }
    catch(err){
        // handle error here
        throw err
    }
    var inspection = [];
    var data = response.inspection_data;
    for ( var i = 0; i<data.length; var item = data[i]
        var fielduser = item.fielduser_id
        try{
            var user = await db.fielduser.findOne({'_id': mongoose.Types.ObjectId(fielduser)})
        }
        catch(err){
             // handle error
        }            
        inspection.push({inspection_name:item.inspection_name,field_user_name : user.owner_name})
   }

})

Upvotes: 2

Milan Velebit
Milan Velebit

Reputation: 2027

Using mongoose would be the easy way out, it returns Promises for all query and save functions, so you'd simply do: YourModel.findOne({params}).then(() => {...})

If you're unable to do that, in your case, a 'promisified' example would be:

var findAndFillArray = (project_id) => new Promise((resolve) => {
    .... your previous code here .... 
    inspection.push({inspection_name:item.inspection_name,field_user_name : 
      user.owner_name})
    if (data.length === inspection.length){  // Or some other preferred condition
       resolve(inspection);
    }
})

Then you'd call this function after you get the id, like any other function:

var id = req.body.project_id;
findAndFillArray(id).then((inspection_array) => {
    res.send(inspection_array) // Or whatever
})

Now, map and all list functions are synchronous in JS, are you sure the error is due to that?

Upvotes: 0

Related Questions