Adam Adam - 1 year ago 259
AngularJS Question

What is the Angular ui-router lifecycle? (for debugging silent errors)

The best I've found is It doesn't go as deep as, for example, the order in which

, and

A great answer format would be clean. Something like:

  1. Initial pageload of state foo:

    1. Angular lifecycle step 1

    2. UI router lifecycle step 1

    3. UI router lifecycle resolves occur

    4. UI router lifecycle onEnter fires

    5. Angular lifecycle step 2

  2. State change foo -> bar

    1. $stateChangeStart
      event fires

    2. foo

    3. bar

    4. templateUrl
      gets the template

    5. UI router plugs back into the Angular lifecycle in the digest loop (or wherever).

  3. Nested states

  4. Multiple named views:

  5. ui-sref clicked

Etc... Thanks!

EDIT: Debugging functions provided enough insight to meet the need. See my answer below for a snippet.

Answer Source

After some experimenting, I figured out how to see into the lifecycle well enough to debug my app and get a feel for what was happening. Using all the events, including onEnter, onExit, stateChangeSuccess, viewContentLoaded from here, gave me a decent picture of when things are happening in a way that's more both more flexible and specific to my code than a written out lifecycle. In the app module's "run" function, I placed:

This code would have saved me days of time and confusion if I started using it when I first started with Angular and UI-router. UI-router needs a "debug" mode that enables this by default.

$rootScope.$on('$stateChangeStart',function(event, toState, toParams, fromState, fromParams){
  console.log('$stateChangeStart to ''- fired when the transition begins. toState,toParams : \n',toState, toParams);
$rootScope.$on('$stateChangeError',function(event, toState, toParams, fromState, fromParams, error){
  console.log('$stateChangeError - fired when an error occurs during transition.');
$rootScope.$on('$stateChangeSuccess',function(event, toState, toParams, fromState, fromParams){
  console.log('$stateChangeSuccess to ''- fired once the state transition is complete.');
// $rootScope.$on('$viewContentLoading',function(event, viewConfig){
//   // runs on individual scopes, so putting it in "run" doesn't work.
//   console.log('$viewContentLoading - view begins loading - dom not rendered',viewConfig);
// });
  console.log('$viewContentLoaded - fired after dom rendered',event);
$rootScope.$on('$stateNotFound',function(event, unfoundState, fromState, fromParams){
  console.log('$stateNotFound ''  - fired when a state cannot be found by its name.');
  console.log(unfoundState, fromState, fromParams);