Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular UI router - access state params in parent

I have an Angular App using the great ui-router.

My setup looks like:

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

    $stateProvider

    // PROJECT DETAIL
    .state('project', {
        url: '/project/:projectId/',
        resolve: {
            /* some base api calls */
        },
        views: {
            'task-list': {
                templateUrl: 'partials/task_list.tmpl.html',
                controller: 'TaskListCtrl',
                resolve: {
                    tasks: function ($stateParams, ConcernService) {
                        return ConcernService.get('project-tasks/', $stateParams.projectId);
                    },
                }
            },
            'concern-instance': {
                /* some resolved variables */
            }
        }
    })
    .state('project.task', {
        url: 'task/:taskId/',
        views: {
            'concern-instance@': {
                /* some different resolved variables */
            },
        }
    })

This all works like butter. However in my task_list template when in state project.task, I want to be able to access the taskId param so I can highlight active nav links, even when the url is #/project/123/task/456/ the taskId is empty. I understand that this is because templates only have access to params declared for that state. So if I want to get the taskId in the project.task state, how should I do it? Do I need to re-declare the task-list in project.task?

like image 887
Darwin Tech Avatar asked Apr 08 '14 19:04

Darwin Tech


People also ask

Why do we need to access the router/url in angular?

Skyrocket your Angular skills to the top. Join 78,561 developers pushing their limits. With the router/URL being an application’s “source of truth”, we need to be able to access parts of the URL for data purposes, such as grabbing a dynamic :id property from the URL, passing it into a service and bringing back the relevant data.

How to get parameters from URL in UI-router?

With ui-router, it's possible to inject either $state or $stateParams into a controller to get access to parameters in the URL.

What is the difference between $state and $stateparams in parentcontroller?

If you are in state parent.child, then $stateParams in parentController will evaluate url-based params of parent, but not those of parent.child. See this issue. On the other hand, $stateParams can preserve custom objects, types, etc. while $state.params would "convert custom objects into plain objects".

Why would you use $state params?

Another reason to use $state.params is for non-URL based state, which (to my mind) is woefully underdocumented and very powerful. I just discovered this while googling about how to pass state without having to expose it in the URL and answered a question elsewhere on SO.


2 Answers

I have noticed $state.params contains the child state params. Can't seem to find any documentation on it. It just works

like image 21
Ladmerc Avatar answered Oct 16 '22 17:10

Ladmerc


In the UI-Router documentation here they explain that

"the $stateParams object will only contain the params that were registered with that state."

You can only have access to parent state parameters in a child state using the resolve property on the parent.

Put this on your 'project' state (parent):

...    
resolve: {
    // Expose projectId parameter to child states
    projectId: ['$stateParams', function ($stateParams) {
        return $stateParams.projectId;
    }]
},

Then inside your controller for your state 'project.task' (child) you should have access to both

$stateParams.projectId

and

$stateParams.taskId
like image 138
dwp4ge Avatar answered Oct 16 '22 17:10

dwp4ge