"$apply already in progress" error

179 views
Skip to first unread message

Tobi Reif

unread,
Jul 29, 2013, 7:57:44 AM7/29/13
to ang...@googlegroups.com
Hi

With an earlier version of my web app I got the "$apply already in
progress" error. Unfortunately I can't reproduce it.

How to ensure that the error won't happen again?

Where to place the $apply call and the $timeout call?

Here's a reduced version: http://jsfiddle.net/gJ7DK/7/ .
("onlineStatusData" is a ref to a Firebase [1] location that can fire
the event at any moment, async, and with high frequency.) (If you open
the JSFiddle in one more window, you'll see one more name & ID. Close ->
one less.)

https://github.com/angular/angular.js/wiki/When-to-use-$scope.$apply%28%29
Should I wrap the Firebase callback (setUserAry in the line
onlineStatusData.on('child_added', setUserAry) in $scope.$apply() ? In
the controller?

Tobi

[1] (Info: Firebase https://www.firebase.com/ is a BaaS which syncs data
across clients.)

--
http://tobireif.com

Tobi Reif

unread,
Aug 5, 2013, 8:20:00 AM8/5/13
to ang...@googlegroups.com
Hi

Explanation: The code states that whenever a user timer ends, a user
should get deleted from the user array "usersOnline", and Angular should
update the UI. And it states that whenever a Firebase child_added event
fires, the user array should get updated, and Angular should update the UI.

All this is fine, and works well.

But when Angular gets a request to update the UI while it already is
processing such a request, it raises the mentioned error
(if I understood that correctly).

How to ensure that the error doesn't happen again? eg Where to place the
$apply call and the $timeout call?

Tobi

--
http://tobireif.com

Tobi Reif

unread,
Aug 8, 2013, 5:51:33 AM8/8/13
to ang...@googlegroups.com
Currently I have the below structure, no "$apply already in progress"
error thus far (with this structure).

I'm using $timeout,0,true in order to try to ensure that the UI-update
cycles don't overlap.

Does that make sense?

Here's the structure:

angular.module('presence')
.service('usersService', function($timeout) {
this.updateList = function(usersOnline, snapshot) {
// ...
if (!user) {
user = {
// ...
remove: function() {
$_.delFromAry(usersOnline, function(item) {
return item.id == user.id;
});
},
// ...
};
$timeout(
function() {
usersOnline.push(user);
},
0,
true
);
}
user.removalTimer = $timeout(
function() {
user.remove();
},
2000,
true
);
};
});

angular.module('presence')
.controller('ctrl',
function($scope, usersService) {
$scope.usersOnline = [];
function setUserAry(snapshot) {
usersService.updateList($scope.usersOnline, snapshot);
}
// Can fire at any time, async.
onlineStatusData.on('child_added', setUserAry);
}
);

Tobi

--
http://tobireif.com

Vojta Jína

unread,
Aug 9, 2013, 2:06:26 AM8/9/13
to ang...@googlegroups.com
Tobi,

How to ensure that the error won't happen again?
Have some e2e tests at least for common scenarios.

Where to place the $apply call and the $timeout call?
Call $apply() whenever you execute some JS code from outside of Angular. That is typically from DOM event listener, or any async code like XHR request - if you use $http, you don't have to worry about $apply() as it already does it for you.

In you case, Firebase event listener is outside the Angular world too and so you have to do $apply(). It's a good practice to take care of $apply at one place, here's my implementation of a trivial chat using Firebase (based on your fiddle):

The confusing thing is that Firebase does fire "child_added" synchronously if it's a local add (not data coming from some other client).

Hope this helps,
Vojta





--
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+unsubscribe@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/groups/opt_out.

Reply all
Reply to author
Forward
0 new messages