Skip to content

Instantly share code, notes, and snippets.

@siongui
Last active April 7, 2020 08:49
Show Gist options
  • Save siongui/4969449 to your computer and use it in GitHub Desktop.
Save siongui/4969449 to your computer and use it in GitHub Desktop.
AngularJS safe $apply (prevent "Error: $apply already in progress")
$scope.safeApply = function(fn) {
var phase = this.$root.$$phase;
if(phase == '$apply' || phase == '$digest')
this.$eval(fn);
else
this.$apply(fn);
};
// OR
function safeApply(scope, fn) {
var phase = scope.$root.$$phase;
if(phase == '$apply' || phase == '$digest')
scope.$eval(fn);
else
scope.$apply(fn);
}
@akarelas
Copy link

I even more like this, from this page:

    angular.module('ng').run(['$rootScope', function($rootScope) {
        $rootScope.safeApply = function(fn) {
            var phase = this.$root.$$phase;
            if(phase == '$apply' || phase == '$digest') {
                if(fn && (typeof(fn) === 'function')) {
                    fn();
                }
            } else {
                this.$apply(fn);
            }
        };
    }]);

@amatiasq
Copy link

@akarelas This does the same but looks more readable to me

angular.module('ng').run(['$rootScope', function($rootScope) {
  $rootScope.safeApply = function safeApply(operation) {
    var phase = this.$root.$$phase;
    if (phase !== '$apply' && phase !== '$digest') {
      this.$apply(operation);
      return;
    }

    if (operation && typeof operation === 'function')
      operation();
  };
}]);

@Hank-wood
Copy link

Hank-wood commented Apr 29, 2017

i have issue
somethims this.$root.$$phase is undefined

route.js:806 Uncaught TypeError: Cannot read property '$$phase' of null
    at p.$rootScope.safeApply

change like this?


angular.module('ng').run(['$rootScope', function($rootScope) {
    $rootScope.safeApply = function(fn) {
        
        if (this.$root && this.$root.$$phase) {
            var phase = this.$root.$$phase;
            if (phase == '$apply' || phase == '$digest') {
                if (fn && (typeof(fn) === 'function')) {
                    fn();
                }
            } else {
                this.$apply(fn);
            }
        } else {
            $scope.$apply(fn);
          
        }

    };
}]);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment