0

I have a piece of code that needs to do the following :

  1. For each Sensor objects in the array, get the Template ID first.
  2. Search the Template Schema DB, get the zipcode of the corresponsing Template ID got.
  3. From the zipcode, generate the URI
  4. Make the requestAPI call
  5. Get the output of the API and store it in the DB for that sensor object.

I am having problem with step 5, storing the result in the DB for each SenObject. I guess the problem is since newSensorObjectRes is defined locally in the test(), it can't be used outside. How else can I store the results for each object?

var arr = [];
function SenObj (id)
{
  this.Objnum = 10;
  this.Template = id;
  this.Type = "AirFlow";
  this.UserID = "Jessi";
}
// To store the results from the AIR API
var sensorResults = new Schema({
  //reqId: {type: Number, required: true, unique: true},
  //sensorId: {type: Number},
  SenObj: {type: Number},
  status: {type: String, default: 'Undefined'}
})
var SensorObjectRes = connUserSensors.model('SensorObjectRes', sensorResults)

//API:To create Sensor Objects when user requests for template
// When user makes a request to create a new Template,we get the tempate ID he has requested.
// We use the ID to create a Sensor Object.We might need the request id too here ??
// The array arr[] holds all the sensor obects..

app.get('/ProvisionTemplate/:id', function (req, res) {
  var id = req.params.id;
  console.log("Server recieved a GET /ProvisionTemplate/" + id + " request");
  Template.findOne({templateId: parseInt(id)},function (err, data) {
    if (err) return console.error(err);
    console.log(data);
    res.json(data);
    // Create an Object here
    var user1 = new SenObj(id);
    console.log(user1.UserID);
    arr.push(user1);
  });
});
console.log("The array objects are :");
for (i = 0; i < arr.length; i++)
{
  console.log(arr[i]);
}
var output = ""
function test()
{
  var zip = "";
  console.log("Interval reached");
  for (i = 0; i < arr.length; i++)
  {
    // For each Sensor objects in the array, get the Template ID first.
    // Search the Template Schema DB, get the zipcode of the corresponsing Template ID got.
    // From the zipcode, generate the URI
    // Make the requestAPI call
    // Get the output of the API and store it in the DB for that sensor object.
    console.log(arr[i]);
    console.log(arr[i].Template);
    var tem = arr[i].Template;
    Template.findOne({templateId: tem},function (err, data)
    {
      if (err) return console.error(err);
      console.log(data.zipcode);
      zip = data.zipcode;
      var uri_1 = "http://www.airnowapi.org/aq/observation/zipCode/current/?format=application/json&zipCode=";
      var uri_2 = "&distance=25&API_KEY=1035C2AC-CDB8-4540-97E4-0E8D82BA335A";
      var url = uri_1 + zip + uri_2;
      console.log(url);
      requestApi(url, function (error, response, body)
      {
        if (!error && response.statusCode == 200)
        {
          console.log(body);
          //console.log(arr[i])
          var newSensorObjectRes = new SensorObjectRes({"SenObj": 1 ,"status": body});
          newSensorObjectRes.save(function (err, data)
          {
            if (err)  return console.log("error updating");
              console.log(data);

          })
        }
      })

    });
  }
}
var interval = setInterval(test, 10000);


newSensorObjectRes.find(function (err, data)
{
  if (err)
  {
    console.log("Could not find EC2Server db");
    return;
  }
  console.log(data)
}) 
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
Jessi Ann George
  • 319
  • 1
  • 2
  • 9
  • 2
    Many of the APIs you are using are asynchronous, but it seems you expect them to be synchronous. I recommend to read [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](http://stackoverflow.com/q/23667086/218196), I believe that's your issue. But you are also right that `newSensorObjectRes` cannot be used outside of `test`. The question is, why do you want to? – Felix Kling May 13 '16 at 07:59
  • The idea is to store the results in a Database (newSensorObjectRes) which will be called later on in the program to view the data collected.. How can I do this otherwise?Pls help – Jessi Ann George May 13 '16 at 08:06

1 Answers1

0

I believe the issue is having a for loop in your test function. You could be making all your Template requests before you get a response. Try using recursion instead. This will assure that your requests are made in an orderly fashion. Something like this...`

function test(i)
{
  if(i == arr.length){
    console.log("done");
    return;
  }
  var zip = "";
  console.log("Interval reached");
  console.log(arr[i]);
  console.log(arr[i].Template);
  var tem = arr[i].Template;
  Template.findOne({templateId: tem},function (err, data)
  {
    if (err) return console.error(err);
    console.log(data.zipcode);
    zip = data.zipcode;
    var uri_1 = "http://www.airnowapi.org/aq/observation/zipCode/current/?format=application/json&zipCode=";
    var uri_2 = "&distance=25&API_KEY=1035C2AC-CDB8-4540-97E4-0E8D82BA335A";
    var url = uri_1 + zip + uri_2;
    console.log(url);
    requestApi(url, function (error, response, body)
    {
      if (!error && response.statusCode == 200)
      {
        console.log(body);
        var newSensorObjectRes = new SensorObjectRes({"SenObj": 1 ,"status": body});
        newSensorObjectRes.save(function (err, data)
        {
          if (err)  return console.log("error updating");
            console.log(data);
            test(i+1);
        })
      }
    })
  });
}
test(0);
Rbla3066
  • 131
  • 1
  • 5