David Rhoderick
David Rhoderick

Reputation: 352

Data for factory coming too late–Angular.js

I had similar code to this working before and for some reason, this one chunk is not. It's a simple idea; call the function, it calls an $http-based factory to get data and return an array of that data. First is the factory:

app.factory('getSensors', ['data', function (data) {
  return { get : function() {
      data.get('sensors').then(function (results) {
        var sensors = [];

        for(var i = 0; i < results.sensors.length; i++) {
          sensors.push({
            'id'        : Number(results.sensors[i][0]),
            'name'      : results.sensors[i][1],
            'type'      : results.sensors[i][2],
            'device'    : results.sensors[i][3],
            'unit'      : results.sensors[i][4],
            'parent'    : Number(results.sensors[i][5]),
            'latitude'  : Number(results.sensors[i][6]),
            'longitude' : Number(results.sensors[i][7])
          });
        }

        return sensors;
      });
    }
  };
}]);

Which uses the following data service:

app.factory('data', ['$http', function ($http) {
  var serviceBase = '/api/';
  var obj = {};

  obj.get = function (q) {
    return $http.get(serviceBase + q).then(function (results) {
      return results.data;
    });
  };

  return obj;
}]);

And for the call to the factory, I've tried getSensors, getSensors.get, and getSensors.get(), even though I know some of those are wrong. I have also tried not wrapping this code in a function, using a function defined above the return, and returned the array in no object (how it is working in my other function, even though I don't think it is best practice, it's just simpler). I've even swapped the for loop for a forEach.

Basically, the returned value from the getSensors factory always happens before the $http call completes from my use of console debugging, even if the code is in the callback function and after that loop. I am at a loss as to how this is possible after spending 2 hours looking at it and rewriting this code. I maybe am simply missing something obvious or am violating some aspect of Angular.

Upvotes: 1

Views: 171

Answers (1)

GregL
GregL

Reputation: 38121

The critical part you are missing is to return the promise created by the .then() in your getSensors.get() method:

app.factory('getSensors', ['data', function (data) {
  return { get : function() {
      return data.get('sensors').then(function (results) {
        var sensors = [];

        /* for loop (same as before) goes here */

        return sensors;
      });
    }
  };
}]);

Then to use it, just inject the getSensors service as a dependency, and call

getSensors.get().then(function (sensors) { 
    /* do something with sensors array */ 
});

Upvotes: 1

Related Questions