1

I have an angular directive that looks like this:

myApp.directive('foo', function() {
      return {
        template: '<span>{{foo.bar}}</span>',
        restrict: 'E',
        scope: true,
        controller: 'myController'
      };
    });

EDIT I set the directive initially with this controller:

 myApp.controller('myController', function ($scope, MyModel) {
        $scope.foo = MyModel.get();
  });

and it seems to work fine to modify the model from a second controller:

myApp.controller('myOtherController', function($scope, MyModel) {
  setTimeout(function() {
    MyModel.set({
      bar: "biz"
    });
  }, 3000);

});

but not with this controller code:

myApp.controller('myOtherController', function($scope, MyModel) {
   $http.get("/resource").then(function(response) {
    MyModel.set(response.data);
  });
});

I have confirmed that the model updates in both instances, but the directive does not update the view with the $http request.

Here is a Plunker that will give you the general idea.

I have tried all sorts of $timeout/$scope.$apply solutions and they all either do nothing or through a digest in progress error. Any help would be appreciated

Jeremythuff
  • 1,518
  • 2
  • 13
  • 35
  • Where are you setting anything that should be updated? What does your `MyModel` service look like? – Phil Feb 20 '15 at 03:36
  • Maybe, you want to take a look at this: http://stackoverflow.com/questions/16845605/is-it-possible-to-update-parent-scope-from-angular-directive-with-scope-true and this: http://stackoverflow.com/questions/16653004/confused-about-angularjs-transcluded-and-isolate-scopes-bindings/16735433#16735433 – Augusto Barreto Feb 20 '15 at 03:48
  • The model is on the plunker. The example with the time out simple changes the model and that change is automatically propagated to the directive. – Jeremythuff Feb 20 '15 at 05:00

1 Answers1

0

When you use .then(), the data for your response is in response.data

myApp.controller('myController', function($scope, MyModel) {
  $scope.foo = MyModel.get();

   $http.get("/resource").then(function(response) {
    MyModel.set(response.data);
  });

});

The .success() method of a promise passes response.data as the first argument:

myApp.controller('myController', function($scope, MyModel) {
  $scope.foo = MyModel.get();

   $http.get("/resource").success(function(response) {
    MyModel.set(response.data);
  });

});

Also, you initialize $scope.foo = MyModel.get() when you initialize your controller, so the value of $scope.foo will be the old value after you call MyModel.set(). To fix:

myApp.controller('myController', function($scope, MyModel) {
  $scope.foo = MyModel.get();

   $http.get("/resource").then(function(response) {
    MyModel.set(response.data);
    $scope.foo = MyModel.get();
  });

});

Here is a working Plunk

The only change I had to make was in the data being sent from your run function

.run(function($httpBackend) {
    var res = {
        bar: "It WORKED"
    };

Not quite sure what the purpose of the $timeout calls is in your factory implementation, and your MyModel factory seems a bit complicated (I think there are much easier ways to accomplish what you are after).

Joe Enzminger
  • 11,110
  • 3
  • 50
  • 75
  • I made some edit to make my situation more clear. I am actually editing the model from a separate controller. When done with a setTimeout, that change is caught by the directive. When done with $http the change happens, but is not caught by the directive. – Jeremythuff Feb 20 '15 at 05:14
  • Added a working version of your plunk. I'll add comments in a few minutes – Joe Enzminger Feb 20 '15 at 05:47
  • The complication of the model is based on our need to be able to implement many instances of our controllers without each of them firing off api req. Part of it is inspired by code found here: http://youtu.be/lHbWRFpbma4 I will try to inegrate this into our main code, and will let you know :) thanks for the working plunker! – Jeremythuff Feb 20 '15 at 05:57