简体   繁体   中英

Returning empty array in NodeJs using mongoose

I am trying to fill an array with records from a mongoDB database using mongoose. When I am trying to fill the records. It shows an empty array outside the function even though I am declaring the outside the function. Below is the code.

var saveMessageToVariable = function(){
    var records = [];
    var spark_ids = [];
    var obj = new Object();
    Message.find().distinct("spark_id").exec(function(err,data) {
        data.forEach(function (id) {
            if(id != null)
            spark_ids.push(id);
        });
      //  console.log(spark_ids.length);
        spark_ids.forEach(function(spark_id){
                Message.findOne({"spark_id":spark_id}).sort({"date":-1}).exec(function(err,data){
                    obj.spark_id = data.spark_id;
                    obj.meesage = data.message;
                    obj.date = data.date;
                    obj.message_id = data._id;
                    records.push(obj);
   });
        });


    });

console.log(records);

}

When I run this, the log is showing an empty array. How do I resolve this issue?

It's an asynchronous call and as soon as data is fetched from database control shifts to next line and therefore prints the initial value, I would prefer you to use a callback like this:

function(spark_id,callback){
                Message.findOne({"spark_id":spark_id}).sort({"date":-1}).exec(function(err,data){
                    obj.spark_id = data.spark_id;
                    obj.meesage = data.message;
                    obj.date = data.date;
                    obj.message_id = data._id;
                    callback(obj);  

   });
}

function(obj)
{
 records.push(obj);
}

You two other approachs for this:

1) use try and catch block.

2) use async and await keyword.

Cheers!

I don't have much experience with moongoose, but according to the docs it supports promises since Version 4.

Then this should work:

//I assume you'll need this more often
function notNull(value){ return value != null; }

//returns a promise of the records-Array
var saveMessageToVariable = function(){ 

    //returns a promise of a formated message
    function getMessage( spark_id ){
        return Message.findOne({ spark_id })
            .sort({ date: -1 })
            //.exec()
            .then( formatMessage )
    }

    function formatMessage( msg ){
        return {
            spark_id:   msg.spark_id,
            message:    msg.message,
            date:       msg.date,
            message_id: msg._id
        }
    }

    return Message.find()
        .distinct("spark_id")
        //.exec()
        .then(function( ids ){
            //waits for all findOnes to complete, then returns an Array
            return Promise.all(
                ids.filter( notNull ).map( getMessage ) 
            ));
}

I'm not sure, wether you need exec() in this code or not. You should check that.

//usage
saveMessageToVariable.then(function(records){
    console.log(records);
})

btw. saveMessageToVariable doesn't reflect at all what this function does. You should choose a better name.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM