Dejan.S
Dejan.S

Reputation: 19138

$stateChangeSuccess, always the same value of $state.params

I can't wrap my head around this, I'm really struggling with ui-routeand $stateChangeSuccess and $watch, got two issues. I'm trying to change a value of a parameter, when I change the state, click a url. I think it's important to know that I use sub-states. With my current setup I get that the $stateChangeSuccess triggers twice on load, meaning it sets the value right away. What I'm trying to do is to only have it set on change of url.

My route looks like this, I'm trying to set the value of a parameter

.state('medications', {
                url: '/medications',
                templateUrl: '/partials/home.html',
                controller: 'mainController',
                params: { showSection: false },
                resolve: {
                    postPromise: ['medicationservice', function(medicationservice) {
                        return medicationservice.getAll();
                    }]
                }
            })
            .state('medications.add', {
                url: '/add',
                templateUrl: '/partials/home.html',
                controller: 'mainController',
                params: { showSection: true },
            })

in my controller I got the following, where I set the openSesame parameter to false explicitly on init, but as described it triggers and sets it to true.

mainModule.controller('mainController', [
        '$scope',
        '$state',
        '$rootScope',
        'medicationservice',
        function($scope, $state, $rootScope, medicationservice) {
            $scope.medication = {};
            $scope.medications = medicationservice.posts;
            $scope.openSesame = false;

            $rootScope.$on("$stateChangeSuccess", function() {
                $scope.openSesame = true;
                console.log($scope.openSesame);
            });
}]);

in my plunker the state change works once, that is if I use the $rootScope.

Upvotes: 0

Views: 1944

Answers (2)

George Chen
George Chen

Reputation: 6939

The callback of $stateChangeSuccess, you have access toState, fromState. Or check current state name

$rootScope.$on("$stateChangeSuccess", function() {
          if ($state.current.name == "medications.add") {

             $scope.openSesame = true;
          } 

          console.log($scope.openSesame);
});

Upvotes: 1

Abdullah Rasheed
Abdullah Rasheed

Reputation: 3752

You can actually use $stateChangeSuccess without $injecting $rootScope. You can set a listener on the $scope object instead. Take a look at the following plunker.

And the revised code:

(function() {
  var app = angular.module('myApp', ['ui.router']);
  app.controller('mainController', [
    '$scope',
    '$state',
    function($scope, $state) {
      $scope.medication = {};
      $scope.openSesame = false;

      $scope.$on('$stateChangeSuccess',function(event, toState){
        $scope.openSesame = toState.params.showSection;
      });

      $scope.triggerMe = function() {
        alert('yes');
      };
    }
  ]);

  app.config([
    '$stateProvider',
    '$urlRouterProvider',
    function($stateProvider, $urlRouterProvider) {

      $stateProvider
        .state('medications', {
          url: '/medications',
          template: '<div>{{openSesame}}</div>',
          controller: 'mainController',
          params: {
            showSection: false
          }
        })
        .state('medications.add', {
          url: '/add',
          template: '<div>{{openSesame}}</div>',
          controller: 'mainController',
          params: {
            showSection: true
          },
        });

      $urlRouterProvider.otherwise('medications');
    }
  ]);
}());

Click your buttons medication and medication add to see the value change.

Upvotes: 1

Related Questions