js2015
js2015

Reputation: 45

Updating parent scope on UI router state change

When changing state with UI router query params are being added. In this case 'size'

Within the parent controller 'indexAppCtrl' the scope property attached to $stateParams.size doesn't update on state change, however the $stateParams object does.

As a fix I've added a listener on $stateChangeSuccess but it feels hacky. Is there a better way of ensuring the scope is updates with stateParams changes?

app.js

var indexApp = angular.module('indexApp', ['ui.router']);

indexApp.config(function($stateProvider, $urlRouterProvider) {

$urlRouterProvider.otherwise('/home');

$stateProvider
    .state('wizard', {
        url: '/wizard?size',
        templateUrl: 'wizard/wizard.html',
        params: {
            size: 'large'
        }
    })

 });

indexAppCtrl.js

    var indexApp = angular.module('indexApp');

    indexApp.controller('indexAppCtrl', ['$scope', '$stateParams', function($scope, $stateParams) {
        $scope.welcome = "welcome to....";

        $scope.stateParams = $stateParams;
        //updates

        $scope.size = $stateParams.size;
        // doesn't update

        $scope.$on('$stateChangeSuccess', function () {
            $scope.size = $stateParams.size;
            //updates
        });

    }]);

index.html

<html ng-app="indexApp" lang="en" xmlns="http://www.w3.org/1999/html">
<head>
    <meta charset="UTF-8">
    <title>home</title>
</head>
<body>
    <main ng-controller="indexAppCtrl">

        <button ui-sref="wizard">Start the wizard</button>

        <ui-view>

        </ui-view>
    </main>
</body>
</html>

Upvotes: 1

Views: 893

Answers (2)

gnerkus
gnerkus

Reputation: 12019

Your solution is not hacky. The $scope.size property is not updated because the controller is not re-created when the state changes.

The $stateChangeSuccess is the defined way to update a component once the state transition has been completed so your solution is correct.

Upvotes: 1

Pankaj Parkar
Pankaj Parkar

Reputation: 136144

I would say that, just attach the refernce of $state.params(global storage of state parameter) to scope variable, which will be getting updated on & when any changes occur in $state parameters.

$scope.params = $state.params;

Upvotes: 1

Related Questions