Watching for changes in multiple controllers

174 views
Skip to first unread message

Kai Weber

unread,
Feb 15, 2013, 11:11:37 AM2/15/13
to ang...@googlegroups.com
Hello,

I don't get it how to get notified about a change in another controller.

I have two controllers, both share a "Basket" object. One controller shows the
contents of the basket, the other controller can add/delete/change the basket.

I want to get the view controller to display the changed contents if the basket
is modified from the other one.

I created a plunker to show my problem. Clicking on the "Add" adds an item to
the basket but the other controller does not show the correct number of items.

I tried watching and using a service as and intermediate but neither worked.

http://plnkr.co/edit/9ZZltbjHORjO41GMTlRW

Could someone enlighten me please?

Thanks, Kai

Pawel Kozlowski

unread,
Feb 15, 2013, 11:18:36 AM2/15/13
to ang...@googlegroups.com
Hi!

One way of doing this: http://plnkr.co/edit/nxtWcckOcAN7EqSbEwws?p=preview
Another one here: http://plnkr.co/edit/MGGOncPWLDRCArZ3rA8Y?p=preview

Cheers,
Pawel
> --
> You received this message because you are subscribed to the Google Groups "AngularJS" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to angular+u...@googlegroups.com.
> To post to this group, send email to ang...@googlegroups.com.
> Visit this group at http://groups.google.com/group/angular?hl=en-US.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>



--
Looking for bootstrap-based widget library for AngularJS?
http://angular-ui.github.com/bootstrap/

Clint Checketts

unread,
Feb 15, 2013, 11:24:37 AM2/15/13
to ang...@googlegroups.com
One more way of doing this: http://plnkr.co/edit/uHSsZVZdiM5mN7kog4Wg?p=preview

You can $watch a function instead of just a scope variable (similar to Pawel's second example, though he used an expression)

  $scope.$watch(function(){
    return Basket.count(); 
  }, function(){
    $scope.items = Basket.count();
  });

Kai Weber

unread,
Feb 15, 2013, 3:17:42 PM2/15/13
to ang...@googlegroups.com
* Pawel Kozlowski <pkozlowski...@gmail.com>:
Thank you very much! You saved me. I like both of them. Will flip a coin...

Kai Weber

unread,
Feb 15, 2013, 3:18:13 PM2/15/13
to ang...@googlegroups.com
* Clint Checketts <chec...@gmail.com>:
> One more way of doing this:
> http://plnkr.co/edit/uHSsZVZdiM5mN7kog4Wg?p=preview
>
> You can $watch a function instead of just a scope variable (similar to
> Pawel's second example, though he used an expression)
>
> $scope.$watch(*function(){*
> * return Basket.count(); *
> * }*, function(){
> $scope.items = Basket.count();
> });

Looks interessting, too. Thank you for the answer.

Dania

unread,
Feb 22, 2013, 1:07:01 AM2/22/13
to ang...@googlegroups.com
Thats cool. How can you apply  $watch to json response coming from server.  I tried this
$scope.$watch(function(){
    return $http.jsonp(url); 
  }, function(){
    $scope.response = $http.jsonp(url).success(function(data,status,headers,config){
    $scope.Data=data;
}) ;
  });

It runs in an infinite loop and gives me the following exception.

Error: 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: [["fn: function (){\nreturn $http.jsonp(url);\n}; newVal: {}; oldVal: {}"],["fn: function (){\nreturn $http.jsonp(url);\n}; newVal: {}; oldVal: {}"],["fn: function (){\nreturn $http.jsonp(url);\n}; newVal: {}; oldVal: {}"],["fn: function (){\nreturn $http.jsonp(url);\n}; newVal: {}; oldVal: {}"],["fn: function (){\nreturn $http.jsonp(url);\n}; newVal: {}; oldVal: {}"]]
https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.js
Line 7692

Kindly guide me how to resolve this.

Clint Checketts

unread,
Feb 22, 2013, 1:13:10 AM2/22/13
to ang...@googlegroups.com
Remember that watched functions get called potentially several times on each digest, so you want to do minimal work in them.

I think you'd probably prefer a $timeout (http://docs.angularjs.org/api/ng.$timeout) that does your $http call and assigns it to a variable, then any dependent code would watch the assigned variable.


--

Dania

unread,
Feb 22, 2013, 2:12:49 AM2/22/13
to ang...@googlegroups.com
Can we do it without $timeout?? I want my $http call to fire whenever $apply is called. 

Clint Checketts

unread,
Feb 22, 2013, 9:52:39 AM2/22/13
to ang...@googlegroups.com
Sure you can do it without $timeout. Are you saying you want your $http every time anything in the model is updated? Or just when $apply is manually called in your own code?

Help me understand why you need to make $http call so frequently.

Dania

unread,
Feb 25, 2013, 8:07:55 AM2/25/13
to ang...@googlegroups.com
With or without timeout, its no issue. I am populating the logs on my server to the client page. I need to check constantly to the server for any new logs and display them . I used timeout like this

$scope.getData = function(){
$scope.resultResponse= $http.jsonp(url).success(function(data,status,headers,config){
$scope.resultData = data;
$timeout($scope.getData, 5000);
});
}
$timeout($scope.getData, 5000);

and on html template i simply print the results in article tags using ng:repeat for resultData.objects.
The problem is that angular repopulates all article tags within that list of articles after this timeout. I am having difficulty on the output of search filters and showing and hiding detail boxes for these articles, as everything resets again. Also if any call to api does not return with data in that particular object, the data that is already present on view disappears.
How to make angular check the response for changes before rendering to the view.

Clint Checketts

unread,
Feb 25, 2013, 10:47:26 AM2/25/13
to ang...@googlegroups.com
It sounds like the showing and hiding values are being stored in the $scope.resultData, and each call to the server is overwriting the resultData, thus overwriting the show/hide state.

Perhaps storing the show.hide data in a separate parallel structure is what is needed.

The problem with api not returning data for a particular object sounds fishy. If the object isn't being returned by the server, why isn't it? If the reason is that the results returns 20 items and it got bumped to the 21st item, then you'll need to solve for this pagination. I'd solve it by breaking the requests down from a single monolithic request, into smaller ones.

Something like:
1) Fetch ids of recent objects, then iterate over each entry comparing it to the ones I'd already fetched
2) Any items that I didn't have, go out and fetch details individually for each of those (this keeps ones that dropped off the first request from vanishing)

Does this sound like what you are wrestling with?

-Clint


Dania

unread,
Feb 25, 2013, 11:19:01 AM2/25/13
to ang...@googlegroups.com
Yes, i just want my view to get updated only if data is changed, so what i understand i need to store my data from http call in some other variable, manually compare it to resultData and then store it in resultData if response is changed. can i use $watch for this ?

Clint Checketts

unread,
Feb 25, 2013, 11:25:15 AM2/25/13
to ang...@googlegroups.com
You could use $watch to trigger the comparison. You'l probably want a 'deep watch' ($watch('resultDataStore', [function to fire], true) the true instructs angular to compare the contents of the variable, not just the reference)


Reply all
Reply to author
Forward
0 new messages