How to pass an object into a state using UI-router?


I'd like to be able to transition to a state and a pass an arbitrary object using ui-router.

I'm aware that usually $stateParams is used, but I believe this value is inserted into the URL, and I don't want users to be able to bookmark this data.

I'd like to do something like this.

$state.transitionTo('newState', {myObj: {foo: 'bar'}});

function myCtrl($stateParams) {
   console.log($stateParams.myObj); // -> {foo: 'bar'}
};

Is there a way to do this without encoding values into the URL?

In version 0.2.13, You should be able to pass objects into $state.go,

$state.go('myState', {myParam: {some: 'thing'}})

$stateProvider.state('myState', {
                url: '/myState/{myParam:json}',
                params: {myParam: null}, ...

and then access the parameter in your controller.

$stateParams.myParam //should be {some: 'thing'}

myParam will not show up in the URL.

Source:

See the comment by christopherthielen https://github.com/angular-ui/ui-router/issues/983, reproduced here for convenience:

christopherthielen: Yes, this should be working now in 0.2.13.

.state('foo', { url: '/foo/:param1?param2', params: { param3: null } // null is the default value });

$state.go('foo', { param1: 'bar', param2: 'baz', param3: { id: 35, name: 'what' } });

$stateParams in 'foo' is now { param1: 'bar', param2: 'baz', param3: { id: 35, name: 'what' } }

url is /foo/bar?param2=baz.


There are two parts of this problem

1) using a parameter that would not alter an url (using params property):

$stateProvider
    .state('login', {
        params: [
            'toStateName',
            'toParamsJson'
        ],
        templateUrl: 'partials/login/Login.html'
    })

2) passing an object as parameter: Well, there is no direct way how to do it now, as every parameter is converted to string (EDIT: since 0.2.13, this is no longer true - you can use objects directly), but you can workaround it by creating the string on your own

toParamsJson = JSON.stringify(toStateParams);

and in target controller deserialize the object again

originalParams = JSON.parse($stateParams.toParamsJson);

Actually you can do this.

$state.go("state-name", {param-name: param-value}, {location: false, inherit: false});

This is the official documentation about options in state.go

Everything is described there and as you can see this is the way to be done.


Btw you can also use the ui-sref attribute in your templates to pass objects

ui-sref="myState({ myParam: myObject })"

1)

$stateProvider
        .state('app.example1', {
                url: '/example',
                views: {
                    'menuContent': {
                        templateUrl: 'templates/example.html',
                        controller: 'ExampleCtrl'
                    }
                }
            })
            .state('app.example2', {
                url: '/example2/:object',
                views: {
                    'menuContent': {
                        templateUrl: 'templates/example2.html',
                        controller: 'Example2Ctrl'
                    }
                }
            })

2)

.controller('ExampleCtrl', function ($state, $scope, UserService) {


        $scope.goExample2 = function (obj) {

            $state.go("app.example2", {object: JSON.stringify(obj)});
        }

    })
    .controller('Example2Ctrl', function ($state, $scope, $stateParams) {

        console.log(JSON.parse($state.params.object));


    })

No, the URL will always be updated when params are passed to transitionTo.

This happens on state.js:698 in ui-router.