### Router flow from link-to

In this guide we will explore the steps Ember performs when a user
clicks on a link generated by the `link-to` helper. Ember has a number
of useful hooks you can overwrite to run code during the various
phases of the transition.

Lets imagine a user is on the `/about/faq/` page of an application
with the following router.

```app/router.js
Router.map(function() {
  this.route('about', function() {
    this.route('faq');
  });

  this.route('user', { path: '/user/:user_id' }, function() {
    this.route('profile');
  });
});
```

This would mean there are currently three nested active routes in this
application. The `route:application`, `route:about` and the `route:about-faq`.

<img src="../images/guides/routing/active-route.png" alt="Active route" class="highlight">

Lets assume a user clicks on a `link-to` for the `controller:user/profile` like
the one below.

```handlebars
{{#link-to 'user.profile' user}}Visit your user profile{{/link-to}}
```

Ember will perform a number of steps before transition a user to the
user profile page. Broadly these steps are grouped into three phases,
the Pre Transition Phase, the Model Resolution Phase and the Sync
Phase. We will explore these phases in more depth below.

#### Pre-Transition Phase

First Ember will create a transition object. This object is a promise
which will be resolved when the transition is complete or rejected
when the random is aborted. The transition object can be used to abort
the transition by calling `transition.abort()`.

Next Ember will trigger a `willTransition` action on the currently
active routes starting with the leaf-most route (in this example the
`AboutFaqRoute`).

<img src="../images/guides/routing/willtransition-event.png" alt="Active route" class="highlight">

The argument for the `willTransition` action is the transition
object. This gives each active route, the opportunity to decide
whether or not the transition should occur. The code to intercept the
`willTransition` action and abort a transition might looks something
like this.

```app/routes/about-faq.js
export default Ember.Route.extend({
  actions: {
    willTransition: function(transition) {
      if (this.controllerFor('form').get('userHasEnteredData') &&
          !confirm("Are you sure you want to abandon progress?")) {
        transition.abort();
      } else {
        // Bubble the `willTransition` action so that
        // parent routes can decide whether or not to abort.
        return true;
      }
    }
  }
});
```

If the transition is not aborted then Ember will attempt to resolve
the model.

#### Model Resolution / Validation Phase

The purpose of this phase is both to collect and resolve all model
promises for newly entered routes (or routes with updated contexts),
as well as allow for any of the
[beforeModel](http://emberjs.com/api/classes/Ember.Route.html#method_beforeModel)
/
[model](http://emberjs.com/api/classes/Ember.Route.html#method_model)
/
[afterModel](http://emberjs.com/api/classes/Ember.Route.html#method_afterModel)
hooks to reject elsewhere. If any of these hooks return a promise, the
transition will pause until the promise resolves/rejects.

<img src="../images/guides/routing/route-model-validation.png" alt="Active route" class="highlight">

If the promise rejects, and `error` action is triggered from the
erroring route and upwards with the rejected/thrown error. Calling
`transitionTo` elsewhere will abort the transition as well (but fire
no errors).

#### Sync exit/enter/setup Phase

After the transition has been validated and any models are resolved
ember enters the Sync exit/enter/setup Phase. Here Ember calls
[exit](http://emberjs.com/api/classes/Ember.Route.html#method_exit) on the existing
routes and
[enter](http://emberjs.com/api/classes/Ember.Route.html#method_enter)
/
[setup](http://emberjs.com/api/classes/Ember.Route.html#method_setup)
on the newly entered routes.

<img src="../images/guides/routing/sync-phase.png" alt="Active route" class="highlight">

If any errors are thrown, the transition promise will be rejected and
the `error` action will be triggered from the erroring route and
upwards with the rejected/thrown error.

If no errors are thrown then the internal transition promise is
resolved and the user is now on the profile page.

### More Resources

- [Preventing and retrying transitions](./preventing-and-retrying-transitions)
- [Ember.js: Transition promises, redirects](https://www.youtube.com/watch?v=EwkaMRJ2tMo)
