faridghar faridghar - 5 months ago 48
AngularJS Question

AngularJS $scope.$apply() Dilemma

I'm using AngularJS with Firebase Realtime Database to create a simple list app that syncs across devices. The web client code can be found below.

The problem is that I need to use the $scope.$apply function in my Firebase

on('val')
callback because this callback is executed from outside of AngularJS and without it, the bindings aren't updated. However, when the user enters a new list item and clicks the Add button, I'm seeing a
angular.js:12520 Error: [$rootScope:inprog]
. I assume that this happens because I'm calling the
$digest()
method when I'm already inside a
$digest()
.

So how can I achieve what I'm trying to do? i.e. use the explicit
$digest()
method when the callback is triggered outside of AngularJS and do not use it otherwise.

<html>
<head>
<script src="https://www.gstatic.com/firebasejs/live/3.0/firebase.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
</head>
<body>
<script type="text/javascript">
var config = {
apiKey: "XXX",
authDomain: "XXX",
databaseURL: "XXX",
storageBucket: "XXX",
};
firebase.initializeApp(config);
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
var database = firebase.database();
database.ref().on('value', function(snapshot) {
$scope.$apply(function() {
$scope.items = [];
var result = snapshot.val();
for(var key in result) {
var listItem = result[key];
$scope.items.push(listItem);
}
});
});
$scope.addItem = function () {
database.ref().push().set($scope.addMe);
}
});
</script>
<div ng-app="myApp" ng-controller="myCtrl">
<ul>
<li ng-repeat="x in items">{{x}}</li>
</ul>
<input ng-model="addMe">
<button ng-click="addItem()">Add</button>
</div>
</body>
</html>

Answer

FIX 1 -

Use

$timeout(function(){ 
  $scope.$apply()
  ... write your code here 
},0)

It will be triggered when the digest cycle is completed.

FIX 2 -

$scope.$$phase will return true if the digest cycle is running else false, but it will not be useful in your case as it doesn't provide any callback function.

Also its not recommended to use

Comments