dman
dman

Reputation: 11064

UI Router- stateChangeStart fires like 50 times

UPDATE: I added a console statement, and it seems that this listener handler is invoked like 50 times for this one event. Or it can be said that this event is firing like 50 times. Any idea why? What can be done?

FIX UPDATE:

angular.module("main.loadbalancer").run(function($rootScope, $state, DeviceVal){
  $rootScope.$on('$stateChangeStart', function(event, toState){
    if (DeviceVal.readonly && toState.name == "main.loadbalancer.vips") {
        event.preventDefault();
        $state.transitionTo("main.loadbalancer.readonly",  {id: "534584"});
        console.log(toState);
    }
  });
});

Whenever $state.transitionTo("main.loadbalancer.readonly"); is ran I get a UI Router: RangeError: Maximum call stack size exceeded. Not sure where or what to do.

angular.module("main.loadbalancer").run(function($rootScope, $state, DeviceVal){
  $rootScope.$on('$stateChangeStart', function(event){
    if (DeviceVal.readonly) {
        $state.transitionTo("main.loadbalancer.readonly");
        event.preventDefault();
        return false;
    }
  });
});

angular.module("main.loadbalancer", ["ui.bootstrap", "ui.router"]).config(function($stateProvider) {
  return $stateProvider.state("main.loadbalancer", {
    resolve: {
      waitForDeviceId: function($state, $q, $timeout, DeviceVal) {
        var deferred = $q.defer();
        $timeout(function() {
          if (DeviceVal.lb) {
            deferred.resolve();
          } else {
            deferred.reject();
          }
        }, 1000);
        return deferred.promise;
      }
    },
    url: "device/:id",
    views: {
      "content@": {
        templateUrl: "loadbalancer/loadbalancer.html",
        controller: "LoadBalancerCtrl"
      }
    }
  }).state("main.loadbalancer.vips", {
    url: "/vips",
    templateUrl: "loadbalancer/vip-table.html",
    controller: "VipListCtrl"
  }).state("main.loadbalancer.nodes", {
    url: "/nodes",
    templateUrl: "loadbalancer/node-table.html",
    controller: "NodeListCtrl"
  }).state("main.loadbalancer.admin", {
    url: "/admin",
    templateUrl: "loadbalancer/admin.html",
    controller: "AdminCtrl"
  }).state("main.loadbalancer.readonly", {
    url: "/readonly",
    templateUrl: "loadbalancer/readonly.html"
  });
});

RangeError: Maximum call stack size exceeded
    at http://10.14.213.161:9000/bower_components/angular/angular.js:7004:18
    at Scope.$broadcast (http://10.14.213.161:9000/bower_components/angular/angular.js:12456:15)
    at Object.transitionTo (http://10.14.213.161:9000/bower_components/angular-ui-router/release/angular-ui-router.js:2032:26)
    at http://10.14.213.161:9000/loadbalancer/services/readonly.service.js:4:16
    at Scope.$broadcast (http://10.14.213.161:9000/bower_components/angular/angular.js:12454:28)
    at Object.transitionTo (http://10.14.213.161:9000/bower_components/angular-ui-router/release/angular-ui-router.js:2032:26)
    at http://10.14.213.161:9000/loadbalancer/services/readonly.service.js:4:16
    at Scope.$broadcast (http://10.14.213.161:9000/bower_components/angular/angular.js:12454:28)
    at Object.transitionTo (http://10.14.213.161:9000/bower_components/angular-ui-router/release/angular-ui-router.js:2032:26)
    at http://10.14.213.161:9000/loadbalancer/services/readonly.service.js:4:16 

Upvotes: 4

Views: 1428

Answers (1)

Andrew Eisenberg
Andrew Eisenberg

Reputation: 28757

The problem that you are having is that you are transitioning in your event handler. This is causing an infinite loop. Instead, you need to explicitly avoid broadcasting the $stateChangeStart when inside of your handler. You can use the notify:false flag to do this. Try this instead:

$state.transitionTo("main.loadbalancer.readonly", null, {notify:false});

You can also read the complete API docs.

Upvotes: 4

Related Questions