reggaemahn
reggaemahn

Reputation: 6648

How do you create nested dynamic routes with ember.js where child route replaces parent's template?

On Ember 3.15 (Octane)

I'm trying to create the following routes in my application

/cars
/cars/:car_id
/cars/:car_id/:model_id

The first two are fine and I've been able to create them using ember-cli

ember g route cars
ember g route cars/car

The problem with the third one is that I need the model template to be shown under the cars template, ie. replace the car template. So if I put an {{outlet}} on the car template, the model template is rendered in it fine but obviously with that {{outlet}} nothing happens when I navigate to /cars/5/2

My router looks like this

Router.map(function() {
  this.route('cars', function(){
    this.route('car', { path: ':car_id'}, function() {
      this.route('model', { path: ':model_id' });
    });
  });
});

I've tried using an index route ember g route cars/car/index but the problem with this that the params are not available in the index route and can only be accessed on the car route.

As plan b I've created the car and model routes as top level routes (based on this answer), but I'd like to achieve the above because of a few reasons

So if I have something like this in my car template

<ul>
  {{#each @model.models as |model|}}
    <li><LinkTo @route="model" @model={{model}}> {{model.title}} </LinkTo></li>
  {{/each}}
</ul>

The actual link works properly in that it takes me to the correct model page, however, the url is shown as /cars/undefined/undefined. (Although this is fixable by passing @models={{array @model.id model.id}}, it seems like a workaround at this point)

Upvotes: 0

Views: 682

Answers (1)

Lux
Lux

Reputation: 18240

The solution is indeed to use the index route.

So have cars.car.index and cars.car.model. However you should use the cars.car route to load the common car model. Then you can access it in the cars.car.index route with this.modelFor('cars.car').

Then you can access the params.car_id in the cars.car route, use it to load the car, and then access this car from the cars.car.index and cars.car.model routes with modelFor.

Upvotes: 1

Related Questions