Lugaru
Lugaru

Reputation: 1460

Angular: ui-router how to pass data object or some parameter to other controller through state

I'm already read about resolve, data for ui-router but still can not get how I can solve my problem?

View 1 HTML:

<a ui-sref="configuration.settings.list"><span>Settings</span></a>
<a ui-sref="configuration.settings.personal({user: userId})"><span >Personal</span></a>

userId is variable which is defined in the controller for current view.

Route definition:

angular.module("app").config(["$stateProvider", "$urlRouterProvider", "$locationProvider", 
function($stateProvider, $urlRouterProvider, $locationProvider) {


    $stateProvider

    .state('configuration.settings.lis', {
        url: '/',
        templateUrl: 'html/settings',
        controller: 'settingsController',
    }),
    .state('configuration.settings.personal', {
        url: '/:userId',
        templateUrl: 'html/settings',
        controller: 'personalController',
    }),

I can access userId in personalController through stateParams.

Question: I want pass object or some parameter from View 1 to personalController without `stateParams. Is it possible?

Something like that:

<a ui-sref="configuration.settings.personal({myDamnCooLObject})"><span >Personal</span></a>


.state('configuration.settings.personal', {
        url: '/', <-- NO attributes here!!!
        templateUrl: 'html/settings',
        controller: 'personalController',
        data: {{myDamnCooLObject}} <-- THIS object or parameter shuld be accesseble from 'personalController'
    })

Upvotes: 0

Views: 3153

Answers (1)

Chad Robinson
Chad Robinson

Reputation: 4623

$stateParams are only guaranteed to be preserved for target routes that use them. ui-router actually keeps this object clean so you can't just stuff random things into it.

I've had good luck using a service as a manager object to persist items between views. For example, I have an app that has a user profile page and a photo gallery as a separate view. I want a lot of the user's core data over in the gallery because there's a title with their name, links back, a little bio box on the side, etc.

The way I wired this up, both views have a user ID in their URL as a parameter. I have a manager that maintains a cache of user data, and a getter that returns a promise to return it. In both states, I have a resolve block that takes the user ID and asks the manager for the whole data object. The manager makes a Web service call to get the data the first time, and immediately resolves for the second call (doesn't matter who gets there first). It works very well and it's lightweight.

In your example you don't want a parameter in the URL at all, but the model could work the same way. Services are global singletons so you can use them as a dumping ground for all kinds of things to be passed around and persisted through things like state transitions. Obviously this is a slippery slope because there are many bad programming practices that are also enabled once you start doing this - but with care and good patterns, it's a very useful technique.

Note that a lot of people actually use $rootScope for this same purpose - it has basically the same effect. But I personally believe a service is better because that way you have a very explicit, defined wrapper around this data you need to pass around, it's much more testable, and it's easier to document it. With $rootScope you're just dumping raw variables into a huge pile and it becomes a pile of spaghetti to pick apart later, especially if you accidentally re-use a variable name. That's causes all kinds of hard-to-find bugs. With a service you can go so far as to use getters/setters, and you could even wire the state transition ($state.go()) call into the setter.

Upvotes: 1

Related Questions