ctb ctb - 2 months ago 6
AngularJS Question

Angular service not exposing value as expected

I'm having a problem getting at values in my service from the controller. My service looks like this:

angular.module('someApp').factory('someSvc', SomeSvc);

function SomeSvc($http) {
var colors = [];
function loadColors() {
return $http.get('SomeApi/GetColors')
.then(function (result) {
//colors = result.data.colors;//<-this doesn't work
//angular.copy(result.data.colors, colors);//<-this works
});
}
return {
loadColors: loadColors,
colors: colors
};
}


Then my controller might make a call like this:

someSvc.loadColors().then(function(){vm.colors = someSvc.colors;});


So, when I debug, if I set a breakpoint in the controller where the assignment to vm.colors is made, the colors property exposed on the someService object has just an empty array or any array with the expected values depending on which of the two commented-out lines I use in the service.

If I set a breakpoint in the service where the assignment to colors is made, the variable colors always has the expected values (e.g., let's say ["red", "yellow", "green"] is what comes back from the http call). So I can watch the controller trigger the http call, watch the value come back and get assigned to colors in the service, but then the controller just sees an empty array unless I do that angular.copy call.

Also, interestingly, if I change the service's return statement to look like this:

return {
loadColors: loadColors,
colors: function() {return colors;}
};


and then in the controller say
vm.colors = someSvc.colors();
then that works just fine as well.

Why is this? Why isn't that array getting passed through?

UPDATE:
I've found that instead of the angular.copy() line, I can alternatively do this, and everything works as expected:

for (var i = 0; i < result.data.colors.length; i++) {
colors[i] = result.data.colors[i];
}


It seems to be that ASSIGNING the object is a problem, while modifying it is ok? Why is that?

Answer

This might work for ya. Guessing it's just a pointer issue maybe?

angular.module('someApp')

.factory('someSvc', function($http)
{
  return {
    colors: [],
    loadColors: function()
    {
      var self = this;

      return $http.get('SomeApi/GetColors').then(function (result) 
      {
        self.colors = result.data.colors;
      });
    }
  };
});
Comments