Reputation: 471
I have AJAX response inside that is deleted object:
request.success(function (data) {
delete $scope.notifications.system[key];
$scope.$apply();
});
I have HTML code with block, that would be appear by condition:
<span ng-show="notifications.system.length == 0" ng-cloak>
DELETED
</span>
So, I tried to use $scope.$apply();
in response at once after removing object. But I have got error:
Error: [$rootScope:inprog] http://errors.angularjs.org/1.3.13/$rootScope/inprog?p0=%24digest
How I can reload template when notifications.system.length
is equal zero?
Upvotes: 1
Views: 229
Reputation: 8970
You could also do the managing of your errors differently. Instead of adding directly to an object you could add the error objects to an array. Deleting can then be done with the following code:
$scope.removeError = function (errorName) {
angular.forEach($scope.notifications, function (error, index) {
if (error.hasOwnProperty(errorName)) $scope.notifications.pop(index);
});
};
Have a look at the demo below and here at jsfiddle.
angular.module('myApp', [])
.controller('mainController', MainController);
function MainController($http, $scope, $timeout) {
$scope.notifications = [{
errorImg: 'failed to load image',
}//,
/*{ // other errors
//errorJS: 'failed to load js'
}*/];
$scope.removeError = function (errorName) {
angular.forEach($scope.notifications, function (error, index) {
//console.log(index, error.hasOwnProperty(errorName), $scope.notifications);
if (error.hasOwnProperty(errorName)) $scope.notifications.pop(index);
//console.log(index, error.hasOwnProperty(errorName), $scope.notifications);
});
};
$scope.clear = function () {
$http.jsonp('http://www.mocky.io/v2/556f7ba53db19a8f05f1e555?callback=JSON_CALLBACK')
.success(function (response) {
//dummy request
//console.log(response, $scope.notifications);
//delete $scope.notifications['errorImg'];
$scope.removeError('errorImg');
}) //.bind(this))
}
}
MainController.$inject = ['$http', '$scope', '$timeout'];
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller='mainController as main'> <pre>{{notifications |json}}</pre>
<!--<button ng-click="main.show()">Show data</button>
<ul>
<li ng-repeat="info in main.data">{{info.test}}</li>
</ul>-->
<button ng-click="clear()">clear error</button>
<ul>
<li ng-repeat="i in dummy">{{i}}</li>
</ul>
<div ng-show="notifications.length == 0">deleted</div>
</div>
Upvotes: 1
Reputation: 964
If you choose to use the $scope.$apply() you should wrap everything in a $timeout and call it like this.
request.success(function(resp){
$timeout(function(){
$scope.$apply(function(){
//do stuff here to the scope.
});
});
});
Passing in a function reference to $apply
will cause it to execute that function then $digest
. Seems a bit strange I know, but the reason for this is that AngularJS typically calls $digest
in response to user interaction, not necessarily to events like $http.success
.
Upvotes: 1
Reputation: 6348
When you use delete on arrays it doesn't change the length of the array instead it replaces the element in the array with undefined. So your ng-show never changes because the length of the array isn't changing. Use splice instead and the array will shorten and your $scope should update at you expect.
$scope.notifications.system.splice($scope.notifications.system.indexOf(key), 1);
you shouldn't need $scope.$apply() for something like this.
Upvotes: 1