Back to Writing

Angular-UI UI-Router reload same Controller with $state.transitionTo()

How to force a controller reload in Angular UI-Router when transitioning to the same state.

Eli Geske 3 min read
angularjs ui-router javascript

When working with AngularJS and the excellent UI-Router, you may run into a situation where you need to reload the current state and its controller, but $state.go() doesn’t seem to do anything because you are already on that state.

This is a common issue when you have a search results page or a filter system where the URL parameters change, but the state name stays the same.

The Problem

By default, UI-Router is smart. If you tell it to go to the state you are already in, it assumes nothing has changed and doesn’t re-instantiate the controller. While this is great for performance, it’s not what you want if you need to refresh data based on new parameters.

The Solution: transitionTo()

The secret is using $state.transitionTo() with the right options. Unlike $state.go(), transitionTo gives you more granular control over the transition.

To force a reload of the controller, you can use the following:

$state.transitionTo($state.current, $stateParams, {
  reload: true,
  inherit: false,
  notify: true,
})

Breaking down the options:

  • reload: true: This is the big one. It tells UI-Router to force a reload of the state, even if it’s the current one.
  • inherit: false: This ensures that we don’t accidentally inherit parameters from the previous transition that might interfere with our new state.
  • notify: true: This ensures that the $stateChangeStart and $stateChangeSuccess events are broadcasted, which is often what triggers the controller initialization.

Using a “Dummy” Parameter

Another trick if you want to keep using $state.go() is to add a “dummy” parameter to your state definition (like a timestamp or a random string) that you update every time you want to force a reload.

// In your state config
.state('results', {
    url: '/results?query&_t',
    ...
})

// In your controller
$state.go('results', { query: 'my search', _t: Date.now() });

This forces the URL to change, which UI-Router sees as a “new” state transition, triggering the controller reload.


Legacy Comments Archive

T
Thomas
November 21, 2013 at 10:20 am

Thanks Eli! I’ve been struggling with this for hours. The transitionTo method worked perfectly for my search page.

E
Eli Geske Author
November 21, 2013 at 11:05 am

You’re welcome Thomas! It’s one of those UI-Router quirks that isn’t immediately obvious in the docs.

S
Sarah J.
December 5, 2013 at 4:15 pm

Does this work with nested states as well? I have a child state that needs to reload without affecting the parent.

E
Eli Geske Author
December 5, 2013 at 4:45 pm

Yes Sarah, it should work fine. If you only want to reload the child, make sure you are passing the specific child state to transitionTo.