Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to link to nested resources in Ember.js?

Assume you have the following routes in an Ember application.

App.Router.map(function() {
  this.resource('series', function() {
    this.resource('serie', { path: '/:serie_id' }, function() {
      this.resource('seasons', function() {
        this.resource('season', { path: '/:season_id' }, function() {
          this.resource('episodes', function() {
            this.resource('episode', { path: '/:episode_id' });
          })
        });
      });
    });
  });
});

How would I link to a specific episode using the linkTo helper that Handlebars provides? In other words, how does Ember figure out what the other parameters of the URL should be, that is, the serie_id and episode_id? The documentation states that I should pass an episode model to the episode route as shown below.

{{#linkTo "episode" episode}}

This is to link to the following URL structure.

/series/:serie_id/seasons/:season_id/episodes/:episode_id/

When I use the linkTo helper like that, Ember throws an error telling me that it cannot call get with id on undefined. I assume that it uses the episode model to figure out what the serie_id and episode_id are and my guess is that the model needs to conform to a specific convention (structure or blueprint) for Ember to find these ids.

These are the aspects that I find most difficult about Ember. It isn't very transparent even if you use Ember in debug mode. Any pointers or references are much appreciated.

UPDATE 1: After some digging, I found out that the route's serialize method is a key element in accomplishing this. However, when I use the linkTo helper as illustrated above, the model passed to the route's serialize method is undefined for some reason (even though it is not when passed to the linkTo helper. The question that led to this discovery can be found here.

UPDATE 2: It turns out that the serieSeason route's serialize method receives the wrong model, an episode instead of a season, when the link is generated. It isn't clear, though, why it is receiving the wrong model. Where does the model parameter of the serialize method come from?

UPDATE 3: The linkTo helper works fine if I return static data from the serialize method of each route involved, which means that the linkTo helper isn't involved in the problem.

like image 333
Bart Jacobs Avatar asked Aug 02 '13 13:08

Bart Jacobs


1 Answers

It turns out that the answer could be found in the properly documented source of Ember ... because that is what one does after searching the web for several days.

The answer is simple. The linkTo helper accepts more than one model. For each dynamic segment of the destination URL, you pass a corresponding model. Each passed model will become the model of the corresponding route in the destination URL. In the example that I describe above, this results in the following.

{{#linkTo "episode" serie season episode}}

The serie model will be passed to the serie route, the season model to the season route, and the episode model to the episode route. What confuses many developers is that the route's model hook isn't triggered when you use the linkTo helper. This isn't too surprising if you realize that the developer provides (or can provide) the model for the corresponding route by passing one or more models (or zero).

Because there isn't much documentation for deeply nested resources, it wasn't trivial to find out how the linkTo helper does its job under the hood. Diving in Ember's source definitely helps getting up to speed with the framework.

like image 97
Bart Jacobs Avatar answered Sep 24 '22 21:09

Bart Jacobs