0

Binding a service/factory variable within a controller works perfectly unless the factory variable is initiated through $http. Can anyone explain why?

NOTE: Since controller.someVariable = factory.someVariable doesn't work. Currently I am referencing the factory variable directly for manipulation as factory.someVariable

Controller:

app.controller('SecondCtrl',function($scope,testFactory){
  $scope.obj = testFactory.obj;
  $scope.factory = testFactory;
  $scope.jsonData = testFactory.jsonData;   //Not Binding

  //Accessing $scope.factory.jsonData works while $scope.jsonData doesn't
});

Factory:

app.factory('testFactory', ['$rootScope','$http',function ($rootScope,$http) {

    var factory = {};

    factory.obj = { 'name':'Jhon Doe'};

    factory.jsonData;

    factory.fromjson = function() {
      $http.get("data.json")
        .success(function(data){
           factory.jsonData  = data.result;
        })

    }

    factory.fromjson();

    return factory;

}]);

Plunker: http://plnkr.co/edit/wdmR5sGfED0jEyOtcsFz?p=preview

7
  • $http is async, you need to return the promise, you are trying to return immediately the data even if it hasn't come back from the server yet. because these are both primitives, and not objects, they aren't "bound" to each other, you are trying to assign the value of one to the value of the other. Commented Oct 17, 2015 at 7:58
  • The factory.jsonData is only updated when the data is received from the server. At that time the controller variable that references the factory variable must update itself right? Commented Oct 17, 2015 at 8:01
  • the controller variable isn't going to update itself, no. These are not objects, they are primitives. In the first case, you are accessing the primitive property of the factory object, in the second case, you are accessing a primitive on $scope. Commented Oct 17, 2015 at 8:02
  • 1
    you still misunderstand. your second option is not a reference assignment, it is a value assignment. therefore, $scope.jsonData can only receive the value that is present on testFactory.jsonData at the time of assignment. If these were objects, then they would be a reference assignment instead. This is not an angular issue, but a javascript assignment issue. Commented Oct 17, 2015 at 8:08
  • 1
    this is one of the most common pitfalls of angular, and is the commonly mentioned, but never clearly explained, "Always use a dot" argument. Commented Oct 17, 2015 at 8:12

1 Answer 1

1

As I've mentioned in the comments, the reason this is occurring is because $scope.jsonData = testFactory.jsonData; is a value assignment, and unfortunately that value isn't available from the server yet when this assignment occurs. the other assignments work because they are reference assignments.

One quick but dirty way to solve this would be to declare factory.jsonData = {}; instead of factory.jsonData;. This would change the call to a reference assignment (object to object) and allow changes to one to propagate to the other.

Sign up to request clarification or add additional context in comments.

1 Comment

I have a similar question but with a different objective, would like your opinion on it. stackoverflow.com/questions/33319779/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.