15

I just started learning angularjs and I am using angular-ui-router. I am trying to send data from one state to another using $state.go but I have no success. Here is what I have so far:

I have not included the html intentionally because I assumed it was not needed if it is needed please tell me and I will add it.

I have configured my states as below:

  $stateProvider
        .state('public', {
            abstract: true,
            templateUrl: 'App/scripts/main/views/PublicContentParent.html'
        })
        .state('public.login', {
            url: '/login',
            templateUrl: 'App/scripts/login/views/login.html',
            controller: 'loginCtrl'
        })

    $stateProvider
        .state('private', {
            abstract: true,
            templateUrl: 'App/scripts/main/views/PrivateContentParent.html'
        })
        .state('private.visits', {
            url: '/visits',
            views: {
                'main': {
                    controller: 'visitsListCtrl',
                    templateUrl: 'App/scripts/visits/views/VisitsList.html'
                }
            }
        });

When my LoginController is invoked it will execute the below code:

loginModule.controller('loginCtrl', ['$state', function ($scope, $state) {

    $state.go('private.visits', { name : "Object"});

}]);

When the private.visits page is active, I am trying to print the $stateParams:

visitsModule.controller('visitsListCtrl', ['$stateParams',
    function ($stateParams) {

        console.log($stateParams);


    }]);

As things state $stateParams is an empty object. I expected it to to contain the object I passed in loginCtrl.

EDIT

It seems that if private.visits url has this url format '/visits/:name' and I also add the property params: ["name"] I get access to the object I send from the public.login state. The side effect is that the parameters are added to the url which is logical.

I tried doing the same thing with a child state with no url, and in this case it seems that I do not have access to the params I passed from public.login.

How do I send data in child states?

Cœur
  • 37,241
  • 25
  • 195
  • 267
aleczandru
  • 5,319
  • 15
  • 62
  • 112

2 Answers2

27

What you have to do is to define the name param in the private.visits state like:

$stateProvider
    .state('public', {
        abstract: true,
        templateUrl: 'App/scripts/main/views/PublicContentParent.html'
    })
    .state('public.login', {
        url: '/login',
        templateUrl: 'App/scripts/login/views/login.html',
        controller: 'loginCtrl'
    })

$stateProvider
    .state('private', {
        abstract: true,
        templateUrl: 'App/scripts/main/views/PrivateContentParent.html'
    })
    .state('private.visits', {

        // NOTE!
        // Previously, we were only passing params as an array 
        // now we are sending it as an object. If you 
        // send this as an array it will throw an error 
        // stating id.match is not a function, so we updated 
        // this code. For further explanation please visit this
        // url http://stackoverflow.com/a/26204095/1132354
        params: {'name': null}, 

        url: '/visits',
        views: {
            'main': {
                controller: 'visitsListCtrl',
                templateUrl: 'App/scripts/visits/views/VisitsList.html',
                resolve: {
                        name: ['$stateParams', function($stateParams) {
                            return $stateParams.name;
                        }]
                    }
            }
        }
    });

And then in the controller access to the name:

visitsModule.controller('visitsListCtrl', ['name',
function (name) {
    console.log(name);
}]);

Hope it help you!

Danny Bullis
  • 3,043
  • 2
  • 29
  • 35
Leandro Zubrezki
  • 1,150
  • 9
  • 12
3

When you say: $state.go('private.visits', { name : "Object"});

You're not passing data to the private.visits state, but rather you're setting a parameter to the private.visits state, which doesn't even support parameters as you have not defined parameters for it in the state config. If you want to share data between states use a service, or if your states have a parent-child relationship then the child state will have access to the parent states data. Seeing as how you don't want the data to sow up in your URLs, I would use a service (getters/setters) to achieve this.

T J
  • 42,762
  • 13
  • 83
  • 138
Mohammad Sepahvand
  • 17,364
  • 22
  • 81
  • 122
  • You dont think parameters is data? Leaves me puzzled. – psp Oct 18 '14 at 02:37
  • The parameters you pass to a state via the URL are primitive types, and are rendered as strings, the OP wanted to pass an object, @Leandro Zubrezki's answer is correct but there is a difference, using params with ui-router allows to pass in objects (this can be considered as 'data' more than route parameters). But yes, Leonardo's answer is better than mine. – Mohammad Sepahvand Oct 18 '14 at 05:38
  • For some reason, ui-router will filter out that parameters object and only include those whose names match path parameters for the state. So, since name isn't a path parameter, it is being stripped out. – DavidA Nov 24 '14 at 21:03