2

I have a function below within the back-end of my application, and the aim is to return all Sensors associated with a specific thingID.

I was approaching this by populating a new array allSensors, however when logged below

console.log(allSensors);
res.send(allSensors)

it is an empty array []

I should also note that individual elements of sensor log correctly

I've moved the

console.log(allSensors)

Into the sensor.findOne loop, and it prints out the elements correctly.

existingThing.sensors.forEach(function (element) {
            Sensor.findOne({_id: element._id}, function (err, sensor) {             
                if(sensor){
                   // console.log(sensor);
                    allSensors.push(sensor); 
                    console.log(allSensors); // this works....
                }     
            })            
        });

Any ideas as to this behaviour? Thanks

//get all sensors associated with thingid
app.get('/api/things/:thingid/sensor', function (req, res) {
    var allSensors = [];
    Thing.findOne({
        thingID: req.params.thingid
    }, function (err, existingThing) {
        if (!existingThing)
            return res.status(409).send({
                message: 'Thing doesnt exist'
            });
        if (existingThing.sensors.length < 0)
            return res.status(409).send({
                message: 'No sensors'
            });      
        existingThing.sensors.forEach(function (element) {
            Sensor.findOne({_id: element._id}, function (err, sensor) {             
                if(sensor){
                   // console.log(sensor);
                    allSensors.push(sensor); 
                }     
            })            
        });
    })
     console.log(allSensors); //empty
     res.send(allSensors); //empty
})
LukeAS
  • 23
  • 3
  • that is not a scoping issue, its an async callback issue, there are plenty of posts to check – juvian Apr 11 '17 at 16:25
  • 2
    Possible duplicate of [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](http://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – Andreas Apr 11 '17 at 16:25
  • Here, it is not enough to ensure that the `forEach` completes – you must also make sure each `findOne` call completes too. You'll probably want the [async](https://caolan.github.io/async/) library for this. – MultiplyByZer0 Apr 11 '17 at 16:26

1 Answers1

1

Install the async library. (It's a seriously useful library, and if you do not use it, you will probably have to reinvent it). Then use this code:

async.each(existingThing.sensors, function(element, _cb) {
    Sensor.findOne({ _id: element._id }, function(err, sensor) {             
        if(sensor) {
            allSensors.push(sensor); 
        } _cb();
    });
}, function() {
    console.log(allSensors);
    res.send(allSensors);
});
MultiplyByZer0
  • 6,302
  • 3
  • 32
  • 48