Getting AngularJS Error: “[$rootScope:inprog] $dig

2019-04-19 06:09发布

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

4条回答
forever°为你锁心
2楼-- · 2019-04-19 06:28

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;
    }
  ]);
})
查看更多
Evening l夕情丶
3楼-- · 2019-04-19 06:28

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.

查看更多
不美不萌又怎样
4楼-- · 2019-04-19 06:35

Add this little method and call it inplace of apply()

function CheckScopeBeforeApply() {
    if(!$scope.$$phase) {
         $scope.$apply();
    }
};
查看更多
姐就是有狂的资本
5楼-- · 2019-04-19 06:43

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

查看更多
登录 后发表回答