Austin Hunter Austin Hunter - 2 months ago 8
Node.js Question

I can't stop the asynchronous

So I am trying to get an array with a loop and the asynchronous nature of nodejs is killing me. Here is my code:



getDevices(userIDs, function(result) {
if (result) {
sendNotification(messageUser, messageText, result);
res.send("Success");
} else {
res.send("ERROR");
}
});

});

function getDevices(userIDs, callback) {
var userDevices = [];
var device = [];

for (var i = 0; i < userIDs.length; i++) {
searchRegisterDevices(userIDs[i], function(result) {
if (result) {
for (var j = 0; j < result.length; j++) {
device = {platform: result[j].platform, token: result[j].token};
userDevices.push(device);
}
} else {
console.log("ERROR");
}
});
}
callback(userDevices);
}







function searchRegisterDevices(userID, callback) {
MongoClient.connect(url, function(err, db) {
if (err) {
console.log(err);
} else {
console.log("We are connected");
}

var collection = db.collection('RegisteredDevices');
collection.find({userID: userID}).toArray(function (err, result) {
if (err) {
console.log("Error: " + err);
} else if (result.length) {
callback(result);
} else {
console.log('No document found');
}
db.close();
});
});





I first need to get all my devices out of my mongodb collection that match the ID in userIDs. SO userIDs is an array of IDs that are tied to devices in the collection. Once I get the device I need to get the device token out of the returned object.

So:
1) call getDevices passing an array of userIDs
2) call searchRegisterDevices with a device ID.
3) searchRegisterDevices returns an array of devices.
4) get the device token/s out of that array and push to userDevices array.
5) return userDevices array
6) call sendNotification with the array of userDevices

I know my issues, I just am having a hard time solving them

Answer

Instead of getting user device for each user you should get them using single query: First: It will reduce number of calls Second: It will save you to handle callbacks o/p.

For it use $in operator.

Change searchdevices method:

function searchRegisterDevices(userID, callback) {
    MongoClient.connect(url, function(err, db) {
            if (err) {
                console.log(err);
            } else {
                console.log("We are connected");
            }

            var collection = db.collection('RegisteredDevices');
            collection.find({
                    userID: {
                        $in: userIDs
                    }).toArray(function(err, result) {
                    if (err) {
                        console.log("Error: " + err);
                    } else if (result.length) {
                        callback(result);
                    } else {
                        console.log('No document found');
                    }
                    db.close();
                });
            });
    }

It will return array of userdevices for passed userids.

Comments