Skip to content
Tim Kindberg edited this page Jul 2, 2013 · 47 revisions

◄ Back (Multiple Named Views)     Next (The Components) ►

Most states in your application will probably have a url associated with them. URL Routing was not an after thought to the state mechanics, but was figured into the design from the beginning (all while keeping states separate from url routing)

Here's how you set a basic url.

$stateProvider
    .state('contacts', {
        url: "/contacts",
        templateUrl: 'contacts.html'
    })

Now when the user accesses index.html/contacts then the 'contacts' state would become active and the main ui-view will be populated with the 'contacts.html' partial. Alternatively, if the user were to transition to the 'contacts' state via transitionTo('contacts') then the url would be updated to index.html/contacts

URL Parameters

Basic Parameters

Often, URLs have dynamic parts to them which are called parameters. There are several options for specifying parameters. A basic parameter looks like this:

$stateProvider
    .state('contacts.detail', {
        url: "/contacts/:contactId",
        templateUrl: 'contacts.detail.html',
        controller: function ($stateParams) {
            // If we got here from a url of /contacts/42
            expect($stateParams).toBe({contactId: 42});
        }]
    })

Alternatively you can also use curly brackets:

// identical to previous example
url: "/contacts/{contactId}" 

Regex Parameters

A bonus to using curly brackets is the ability to set a Regular Expression rule for the parameter:

// will only match a contactId of one to eight number characters
url: "/contacts/{contactId:[0-9]{1,8}}"

Warning: Don't put capturing parentheses into your regex patterns, the UrlMatcher in ui-router adds those itself around the entire regex. You're effectively introducing a second capture group for the same parameter, which trips up the numbering in the child URL. You can use non-capturing groups though, i.e. (?:...) is fine.

Query Parameters

You can also specify parameters as query parameters, following a '?':

url: "/contacts?myParam"
// will match to url of "/contacts?myParam=value"

If you need to have more than one, separate them with an '&':

url: "/contacts?myParam1&myParam2"
// will match to url of "/contacts?myParam1=value1&myParam2=wowcool"

URL Routing for Nested States

Appended Routes (default)

When using url routing together with nested states the default behavior is to concatenate url paths through the inheritance chain.

$stateProvider
  .state('contacts', {
     url: '/contacts',
     ...
  })
  .state('contacts.list', {
     url: '/list',
     ...
  });

Then the state 'contacts.list' is matched when url is '/contacts/list'.

Absolute Routes (^)

If you want to have absolute url matching, then you need to prefix your url string with a special symbol '^'.

$stateProvider
  .state('contacts', {
     url: '/contacts',
     ...
  })
  .state('contacts.list', {
     url: '^/list',
     ...
  });

Now the state 'contacts.list' is matched when url is '/list'.

$stateParams Service

As you saw previously the $stateParams service is an object that will have one key per url parameter. The $stateParams is a perfect way to provide your controllers or other services with the individual parts of the navigated url.

// If you had a url on your state of:
url: '/users/:id/details/{type}/{repeat:[0-9]+}?from&to'

// Then you navigated your browser to:
'/users/123/details//0'

// Your $stateParams object would be
{ id:'123', type:'', repeat:'0' }

// Then you navigated your browser to:
'/users/123/details/default/0?from=there&to=here'

// Your $stateParams object would be
{ id:'123', type:'default', repeat:'0', from='there', to='here' }

◄ Back (Multiple Named Views)     Next (The Components) ►