0

When select date from datepicker it shown $apply already in progress, and console shown error like

Error: [$rootScope:inprog] $apply already in progress

and the directive which I used is:

enter code here

focus: function (e) {
    scope.$apply(function () {
        scope.PresentDateOpened = true;
    });
},
change: function (e) {

    scope.$apply(function () {
        if (element.val() == "") {
            ngModel.$setValidity('validDate', true);
        }
    });
},
blur: function (e) {
    if (element.val() != "") {
        scope.$apply(function () {
            var data = element.val().toString().split('-');
            if (data.length == 3) {
                var month = new Date(data[2], data[1], data[0]).getMonth();
                var day = new Date(data[2], data[1], data[0]).getDate();
                var year = new Date(data[2], data[1], data[0]).getFullYear();

                if (!isNaN(month) && !isNaN(day) && !isNaN(year)) {
                    if (angular.isDate(new Date(day, month, year))) {
                        ngModel.$setValidity('validDate', true);
                        ngModel.$setViewValue(new Date(data[2], data[1] - 1, data[0]), 'dd-MMM-yyyy');
                        ngModel.$render();
                    }
                    else {
                        ngModel.$setValidity('validDate', false);
                    }
                }
Nikolay Kostov
  • 16,433
  • 23
  • 85
  • 123

2 Answers2

0

Instead of scope.$apply use $timeout. More information can be find here https://stackoverflow.com/a/17958847/1324935

Community
  • 1
  • 1
Ara Yeressian
  • 3,746
  • 3
  • 26
  • 36
  • but when click in datepicker it shown that Uncaught TypeError: $timeout is not a function – prasad ambulkar Jul 14 '15 at 07:44
  • $timeout is a standard angular service. You need to inject it first before using it. – Ara Yeressian Jul 14 '15 at 07:52
  • The $timeout(function(){}) is equal to setTimeout(scope.$apply(function(){})) roughly saying. Duo to angular digest loop internal structure you shouldn't call the apply when the digest loop is in progress. You need to defer it to the next event loop cycle that is what setTimeout does. – Ara Yeressian Jul 14 '15 at 12:03
  • if this answer solves your issue please make this answer accepted – Ara Yeressian Jul 14 '15 at 14:58
0

use safe apply.

scope.safeApply(function() {
                    var data = element.val().toString().split('-');
                    if (data.length == 3) {
                        var month = new Date(data[2], data[1], data[0]).getMonth();
                        var day = new Date(data[2], data[1], data[0]).getDate();
                        var year = new Date(data[2], data[1], data[0]).getFullYear();

                        if (!isNaN(month) && !isNaN(day) && !isNaN(year)) {
                            if (angular.isDate(new Date(day, month, year))) {
                                ngModel.$setValidity('validDate', true);
                                ngModel.$setViewValue(new Date(data[2], data[1] - 1, data[0]), 'dd-MMM-yyyy');
                                ngModel.$render();
                            } else {
                                ngModel.$setValidity('validDate', false);
                            }
                        }

                    });


scope.safeApply = function(fn) {
  var phase = this.$root.$$phase;
  if(phase == '$apply' || phase == '$digest') {
    if(fn && (typeof(fn) === 'function')) {
      fn();
    }
  } else {
    this.$apply(fn);
  }
};
ngLover
  • 4,439
  • 3
  • 20
  • 42
  • See the second point https://github.com/angular/angular.js/wiki/Anti-Patterns. Also you should not use $$phase in your application since it's a private variable. – Ara Yeressian Jul 14 '15 at 07:52
  • ya it's true we don't need to use them in our code but these patches help us to perform several tasks like some tricks – ngLover Jul 14 '15 at 07:54
  • Have a look here http://stackoverflow.com/questions/22346990/why-is-using-ifscope-phase-scope-apply-an-anti-pattern – Ara Yeressian Jul 14 '15 at 07:56