Class Route

public
import Route from '@ember/routing/route';

The Route class is used to define individual routes. Refer to the routing guide for documentation.

Show:

Available since v3.6.0

name
String

Sets the name for this route, including a fully resolved name for routes inside engines.

Available since v1.0.0

transition
Transition

This hook is executed when the router enters the route. It is not executed when the model for the route changes.

Available since v1.0.0

resolvedModel
Object

the value returned from model, or its resolved value if it was a promise

transition
Transition
returns
Any | Promise<any>

if the value returned from this hook is a promise, the transition will pause until the transition resolves. Otherwise, non-promise return values are not utilized in any way.

This hook is called after this route's model has resolved. It follows identical async/promise semantics to beforeModel but is provided the route's resolved model in addition to the transition, and is therefore suited to performing logic that can only take place after the model has already resolved.

app/routes/posts.js
import Route from '@ember/routing/route';
import { service } from '@ember/service';

export default class PostsRoute extends Route {
  @service router;

  afterModel(posts, transition) {
    if (posts.get('length') === 1) {
      this.router.transitionTo('post.show', posts.get('firstObject'));
    }
  }
}

Refer to documentation for beforeModel for a description of transition-pausing semantics when a promise is returned from this hook.

Available since v1.0.0

transition
Transition
returns
Any | Promise<any>

if the value returned from this hook is a promise, the transition will pause until the transition resolves. Otherwise, non-promise return values are not utilized in any way.

This hook is the first of the route entry validation hooks called when an attempt is made to transition into a route or one of its children. It is called before model and afterModel, and is appropriate for cases when:

1) A decision can be made to redirect elsewhere without needing to resolve the model first. 2) Any async operations need to occur first before the model is attempted to be resolved.

This hook is provided the current transition attempt as a parameter, which can be used to .abort() the transition, save it for a later .retry(), or retrieve values set on it from a previous hook. You can also just call router.transitionTo to another route to implicitly abort the transition.

You can return a promise from this hook to pause the transition until the promise resolves (or rejects). This could be useful, for instance, for retrieving async code from the server that is required to enter a route.

Available since v3.10.0

returns

any

Allows you to produce custom metadata for the route. The return value of this method will be attached to its corresponding RouteInfoWithAttributes object.

Example

app/routes/posts/index.js
import Route from '@ember/routing/route';

export default class PostsIndexRoute extends Route {
  buildRouteInfoMetadata() {
    return { title: 'Posts Page' }
  }
}
app/routes/application.js
import Route from '@ember/routing/route';
import { service } from '@ember/service';

export default class ApplicationRoute extends Route {
  @service router

  constructor() {
    super(...arguments);

    this.router.on('routeDidChange', transition => {
      document.title = transition.to.metadata.title;
      // would update document's title to "Posts Page"
    });
  }
}

Called when the context is changed by router.js.

Available since v1.0.0

name
String

the name of the route or controller

returns
Controller | undefined

Returns the controller of the current route, or a parent (or any ancestor) route in a route hierarchy.

The controller instance must already have been created, either through entering the associated route or using generateController.

app/routes/post.js
import Route from '@ember/routing/route';

export default class PostRoute extends Route {
  setupController(controller, post) {
    super.setupController(controller, post);

    this.controllerFor('posts').set('currentPost', post);
  }
}

Available since v1.0.0

transition
Transition

This hook is executed when the router completely exits this route. It is not executed when the model for the route changes.

params
Object

the parameters extracted from the URL

transition
Transition
returns
Any | Promise<any>

the model for this route.

Router.js hook.

value
Object
urlKey
String
defaultValueType
String

Deserializes value of the query parameter based on defaultValueType

name
String

the name of the controller

Generates a controller for a route.

Example

app/routes/post.js
import Route from '@ember/routing/route';

export default class Post extends Route {
  setupController(controller, post) {
    super.setupController(controller, post);

    this.generateController('posts');
  }
}

Available since v1.2.0

name
String

the name of the route

models
...Object

the model(s) to be used while transitioning to the route.

Perform a synchronous transition into another route without attempting to resolve promises, update the URL, or abort any currently active asynchronous transitions (i.e. regular transitions caused by transitionTo or URL changes).

This method is handy for performing intermediate transitions on the way to a final destination route, and is called internally by the default implementations of the error and loading handlers.

Available since v1.0.0

params
Object

the parameters extracted from the URL

transition
Transition
returns
Any | Promise<any>

the model for this route. If a promise is returned, the transition will pause until the promise resolves, and the resolved value of the promise will be used as the model for this route.

A hook you can implement to convert the URL into the model for this route.

app/router.js
// ...

Router.map(function() {
  this.route('post', { path: '/posts/:post_id' });
});

export default Router;

Note that for routes with dynamic segments, this hook is not always executed. If the route is entered through a transition (e.g. when using the link-to Handlebars helper or the transitionTo method of routes), and a model context is already provided this hook is not called.

A model context does not include a primitive string or number, which does cause the model hook to be called.

Routes without dynamic segments will always execute the model hook.

// no dynamic segment, model hook always called
this.router.transitionTo('posts');

// model passed in, so model hook not called
thePost = store.findRecord('post', 1);
this.router.transitionTo('post', thePost);

// integer passed in, model hook is called
this.router.transitionTo('post', 1);

// model id passed in, model hook is called
// useful for forcing the hook to execute
thePost = store.findRecord('post', 1);
this.router.transitionTo('post', thePost.id);

This hook follows the asynchronous/promise semantics described in the documentation for beforeModel. In particular, if a promise returned from model fails, the error will be handled by the error hook on Route.

Note that the legacy behavior of automatically defining a model hook when a dynamic segment ending in _id is present is deprecated. You should explicitly define a model hook whenever any segments are present.

Example

app/routes/post.js
import Route from '@ember/routing/route';
import { service } from '@ember/service';

export default class PostRoute extends Route {
  @service store;

  model(params) {
    return this.store.findRecord('post', params.post_id);
  }
}

Available since v1.0.0

name
String

the name of the route

returns
Object

the model object

Returns the resolved model of a parent (or any ancestor) route in a route hierarchy. During a transition, all routes must resolve a model object, and if a route needs access to a parent route's model in order to resolve a model (or just reuse the model from a parent), it can call this.modelFor(theNameOfParentRoute) to retrieve it. If the ancestor route's model was a promise, its resolved result is returned.

Example

app/router.js
// ...

Router.map(function() {
  this.route('post', { path: '/posts/:post_id' }, function() {
    this.route('comments');
  });
});

export default Router;
app/routes/post/comments.js
import Route from '@ember/routing/route';

export default class PostCommentsRoute extends Route {
  model() {
    let post = this.modelFor('post');

    return post.comments;
  }
}

Available since v1.4.0

name
String
returns
Object

hash containing the parameters of the route name

Returns a hash containing the parameters of an ancestor route.

You may notice that this.paramsFor sometimes works when referring to a child route, but this behavior should not be relied upon as only ancestor routes are certain to be loaded in time.

Example

app/router.js
// ...

Router.map(function() {
  this.route('member', { path: ':name' }, function() {
    this.route('interest', { path: ':interest' });
  });
});
app/routes/member.js
import Route from '@ember/routing/route';

export default class MemberRoute extends Route {
  queryParams = {
    memberQp: { refreshModel: true }
  }
}
app/routes/member/interest.js
import Route from '@ember/routing/route';

export default class MemberInterestRoute extends Route {
  queryParams = {
    interestQp: { refreshModel: true }
  }

  model() {
    return this.paramsFor('member');
  }
}

If we visit /turing/maths?memberQp=member&interestQp=interest the model for the member.interest route is a hash with:

  • name: turing
  • memberQp: member
changed
Object

Keys are names of query params that have changed.

totalPresent
Object

Keys are names of query params that are currently set.

removed
Object

Keys are names of query params that have been removed.

returns
Boolean

This action is called when one or more query params have changed. Bubbles.

Available since v1.0.0

model
Object

the model for this route

transition
Transition

the transition object associated with the current transition

A hook you can implement to optionally redirect to another route.

Calling this.router.transitionTo from inside of the redirect hook will abort the current transition (into the route that has implemented redirect).

redirect and afterModel behave very similarly and are called almost at the same time, but they have an important distinction when calling this.router.transitionTo to a child route of the current route. From afterModel, this new transition invalidates the current transition, causing beforeModel, model, and afterModel hooks to be called again. But the same transition started from redirect does not invalidate the current transition. In other words, by the time the redirect hook has been called, both the resolved model and the attempted entry into this route are considered fully validated.

Available since v1.4.0

returns
Transition

the transition object associated with this attempted transition

Refresh the model on this route and any child routes, firing the beforeModel, model, and afterModel hooks in a similar fashion to how routes are entered when transitioning in from other route. The current route params (e.g. article_id) will be passed in to the respective model hooks, and if a different model is returned, setupController and associated route hooks will re-fire as well.

An example usage of this method is re-querying the server for the latest information using the same parameters as when the route was first entered.

Note that this will cause model hooks to fire even on routes that were provided a model object when the route was initially entered.

Available since v1.7.0

controller
Controller

instance

isExiting
Boolean
transition
Object

A hook you can use to reset controller values either when the model changes or the route is exiting.

app/routes/articles.js
import Route from '@ember/routing/route';

export default class ArticlesRoute extends Route {
  resetController(controller, isExiting, transition) {
    if (isExiting && transition.targetName !== 'error') {
      controller.set('page', 1);
    }
  }
}

Available since v1.0.0

name
String

the name of the action to trigger

args
...*

Sends an action to the router, which will delegate it to the currently active route hierarchy per the bubbling rules explained under actions.

Example

app/router.js
// ...

Router.map(function() {
  this.route('index');
});

export default Router;
app/routes/application.js
import Route from '@ember/routing/route';
import { action } from '@ember/object';

export default class ApplicationRoute extends Route {
  @action
  track(arg) {
    console.log(arg, 'was clicked');
  }
}
app/routes/index.js
import Route from '@ember/routing/route';
import { action } from '@ember/object';

export default class IndexRoute extends Route {
  @action
  trackIfDebug(arg) {
    if (debug) {
      this.send('track', arg);
    }
  }
}

Available since v1.0.0

model
Object

the routes model

params
Array

an Array of parameter names for the current route (in the example, ['post_id'].

returns
Object

the serialized parameters

A hook you can implement to convert the route's model into parameters for the URL.

app/router.js
// ...

Router.map(function() {
  this.route('post', { path: '/posts/:post_id' });
});
app/routes/post.js
import Route from '@ember/routing/route';

export default class PostRoute extends Route {
  model({ post_id }) {
    // the server returns `{ id: 12 }`
    return fetch(`/posts/${post_id}`;
  }

  serialize(model) {
    // this will make the URL `/posts/12`
    return { post_id: model.id };
  }
}

The default serialize method will insert the model's id into the route's dynamic segment (in this case, :post_id) if the segment contains 'id'. If the route has multiple dynamic segments or does not contain 'id', serialize will return getProperties(model, params)

This method is called when transitionTo is called with a context in order to populate the URL.

value
Object
urlKey
String
defaultValueType
String

Serializes value of the query parameter based on defaultValueType

controllerPropertyName
String

Serializes the query parameter key

This hook is the entry point for router.js

Available since v1.0.0

controller
Controller

instance

model
Object
transition
Transition

A hook you can use to setup the controller for the current route.

This method is called with the controller for the current route and the model supplied by the model hook.

By default, the setupController hook sets the model property of the controller to the specified model when it is not undefined.

If you implement the setupController hook in your Route, it will prevent this default behavior. If you want to preserve that behavior when implementing your setupController function, make sure to call super:

app/routes/photos.js
import Route from '@ember/routing/route';
import { service } from '@ember/service';

export default class PhotosRoute extends Route {
  @service store;

  model() {
    return this.store.findAll('photo');
  }

  setupController(controller, model) {
    super.setupController(controller, model);

    this.controllerFor('application').set('showingPhotos', true);
  }
}

The provided controller will be one resolved based on the name of this route.

If no explicit controller is defined, Ember will automatically create one.

As an example, consider the router:

app/router.js
// ...

Router.map(function() {
  this.route('post', { path: '/posts/:post_id' });
});

export default Router;

If you have defined a file for the post controller, the framework will use it. If it is not defined, a basic Controller instance would be used.

this[RENDER] is used to set up the rendering option for the outlet state.