Other posts on this error always include someone trying to $apply without using a safe apply, but that's not the case in my example. My function IS successfully returning the data I requested from the API, but I can't clean this bug and it's driving me nuts. Every time before the .success is called in my $http function I get "Error: [$rootScope:inprog] $digest already in progress" in the console. Below are my controller and service. Thanks!
Here's my service including a function to post an $http call with a payload:
Services.service( 'CoolService', ['$q', '$rootScope', '$http', 'Auth', function($q, $rootScope, $http, Auth){
var service = {
create: function(payload){
var deferred = $q.defer();
$http({
'url': '/api/endpoint/',
'dataType':'json',
'method': 'POST',
data: payload
}).success(function(data,status, headers, config){
deferred.resolve(data);
})
.error(function(data, status, headers, config){
deferred.reject("Error in request.");
});
return deferred.promise;
}
}
return service;
}]);
And here's my controller which calls the service:
controllers.controller('CoolCtrl',['$scope', '$modal', '$log','CoolService', function($scope, $modal, $log, CoolService){
getCoolData = function (input_data) {
CoolService.create(input_data).then(function(results){
new_cool = results.results;
}, function(error){
console.log("there was an error getting new cool data");
});
};
var payload = {
user_id: data1,
cool_id: data2,
}
var new_cool_data = getCoolData(payload);
console.log(new_cool_data);
}]);
The log below var new_cool_data gets called before the async operation, but new_cool does get assigned inside the .then statement within getCoolData. Any help getting rid of this bug or making it not crappy in general would be greatly appreciated!
Here's the whole error: https://gist.github.com/thedore17/bcac9aec781ef9ba535b
Add this little method and call it inplace of apply()
function CheckScopeBeforeApply() {
if(!$scope.$$phase) {
$scope.$apply();
}
};
This solve the issue for me. Just add it one time, it you don't need to change you code any more:
https://github.com/angular/angular.js/issues/10083#issuecomment-145967719
.config(function($provide) {
// Workaround for https://github.com/angular/angular.js/issues/10083
$provide.decorator('$rootScope', ['$delegate', '$exceptionHandler',
function($delegate, $exceptionHandler) {
var proto = Object.getPrototypeOf($delegate);
var originalDigest = proto.$digest, originalApply = proto.$apply;
proto.$digest = function() {
if ($delegate.$$phase === '$digest' || $delegate.$$phase === '$apply') return;
originalDigest.call(this);
};
proto.$apply = function(fn) {
if ($delegate.$$phase === '$digest' || $delegate.$$phase === '$apply') {
try {
this.$eval(fn);
} catch(e) {
$exceptionHandler(e);
}
} else {
originalApply.call(this, fn);
}
};
return $delegate;
}
]);
})
I used alternate solution by putting $scope.$apply() in timeout like this and it worked...
setTimeout(function(){
$scope.$apply();
},1);
I think it is just because, angular's apply lifecycle was already running and my manual $apply has interrupted it.
There's an easier solution:
$scope.$evalAsync(function() {
// Code here
});
Or simply:
$scope.$evalAsync();
This avoids the problems caused by $scope.$apply(), though it should be noted that it won't run immediately (that's part of the reason you won't get the inprog error). I use this instead of $scope.$apply() and it has saved me from so much trouble.
See: https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$evalAsync
来源:https://stackoverflow.com/questions/21858841/getting-angularjs-error-rootscopeinprog-digest-already-in-progress-witho