Search code examples
ember.jsember-router

EmberJS redirect when no subroute specified


I have a set of nested routes and templates that I'd like to auto-select the first model if no sub-routes are specified. The route structure is:

App.Router.map(function() {
  this.route('sales', function () {
    this.route('orders', function () {
      this.route('order', { path: ':order_id' });
    });  
  });
});

If the user hits sales.orders then they should be redirected to the first order on the sales.orders model. Making this work is no problem. The issue comes when the user hits sales/orders/:order_id No matter what :order_id is the user is always redirected to the first order in the orders array.

I'm currently performing the redirect in the setupControllerhook of the SalesOrders route as I have some sorting on the controller that needs to be in place prior to redirecting.

App.SalesOrdersRoute = Ember.Route.extend({
  model: function () {
    return this.store.find('order');
  },

  setupController: function (controller, model) {
    controller.set('model', model);
    var firstObject = controller.get('sortedContent').get('firstObject');
    this.transitionTo('sales.orders.order', firstObject);
  }
});

App.SalesOrdersController = Ember.ArrayController.extend({
  sortProperties: ['orderNumber:desc'],
  sortedContent: Ember.computed.sort('model', 'sortProperties')
});

I have a jsbin that shows my issue.

Hitting any specific order will always redirect to the first order in the array (4 in this case).

I need it to keep the deep linked url and only redirect when no order is specified.

I feel like this question and this question are both similar to what I'm trying to do except neither addresses auto-selecting the first item if no sub-routes are specified.


Solution

  • You should do the redirect in your SalesOrdersIndex route. The additional index route of each route will only be created when it matches the complete URL mapping. So for any url that isn't exactly "sales/orders" it will not be created. Just what you want.

    App.SalesOrdersIndexRoute = Ember.Route.extend({
      setupController: function (controller, model) {
        controller.set('model', model);
        this.controllerFor('salesOrders').set('model',model);
       var firstObject = this.controllerFor('salesOrders').get('sortedContent').get('firstObject');
        this.transitionTo('sales.orders.order', firstObject);
      }  
    }); 
    

    jsbin: 4 3 2 1 redirect to 4