1

I have the same problem as described here but do not understand how it applies to my situation, since I have no 'show' route.

I inherited this app, and the router.js looks like this:

App.Router.map(function() {
  this.route('index', {
    path: '/'
  });
  return this.resource('parent', {
    path: '/:parent_id'
  }, function() {
    this.resource('games', {
      path: '/games'
    });
    return this.resource('game', {
      path: '/game/:game_id'
    });
  });
});

The backend is Rails, and when the /games url is hit in Ember, it calls the games Index action in the Rails GamesController, as expected.

The games template renders each game:

<ul class="gamesList">
{{#each game in sortedGames}}
  {{#link-to 'game' game class='gameItem u-cf' tagName='li'}}
    <div class="gameItem-name u-before6of12 u-after1of12">{{game.name}}</div>
    <div class="gameItem-description u-before6of12 u-after1of12">{{game.description}}</div>
  {{/link-to}}
{{/each}}

but when the game link is clicked, it loads the game from Ember store, and does not make a request to the API.

I need it to make a request to the API because: 1. The list of games includes only name and description, since the list can include many games, so we only want to load a subset of the data for each game. 2. An individual game, loaded by the Rails Show action, should use a different serializer to load all the additional content for a single game (including embedded child objects).

This is the Games route:

App.GamesRoute = Ember.Route.extend(Easypeasy.ResetScroll, {
  model: ->
    return this.store.find('game', {
      parent: @modelFor('parent').get('slug')
    })
})

and this is the Game route:

App.GameRoute = Ember.Route.extend(App.ResetScroll)

How do I trigger Ember to load the single game that the user clicks on?

Community
  • 1
  • 1
rmcsharry
  • 5,363
  • 6
  • 65
  • 108

1 Answers1

4

So ember data by default will not re-request data that it has already loaded. If your parent route's model loaded an array of games, then the child route that requires a specific game will not make another request. The following code

this.store.findRecord('game', params.game_id)

will simply look inside the in-memory ember-data store and return the game record.

In cases where you need to make another request, you can force the behavior via an option

this.store.findRecord('game', params.game_id, {reload: true}); 

You can read about this behavior here: http://emberjs.com/api/data/classes/DS.Store.html#method_findRecord

Do note that I am linking to ember 2.0 docs, but this works with ember data 1 as well. If you are using ember data < 2.0, your call will probably look like this

this.store.find('game', params.game_id, {options: reload});

Another way to do this is to call reload() on the model instance itself. This will also prove useful if you know that data has change on the server, and you want to re-request data for a model after some action has occurred.

And finally, Ember Data 2.0 provides even more options, where you can quick load data from the store, but also make a request in the background to fetch more info. This can be either good or bad depending on whether you want your users to see a flash of missing content, or whether you want them to wait.

  • Thanks for the fast reply, but what I find strange is nowhere in the code is this line: this.store.findRecord('game', params.game_id). If it is not doing a findRecord, how is it loading it from the store? I tried adding that to the GameRoute (which you can see above is basically empty) but that gives an error (cannot read property 'find' of undefined) – rmcsharry May 04 '16 at 09:21
  • Sorry it gives this error: Error while processing route: game this.store.findRecord is not a function - I guess this is because I am on ember 1.12. So I tried your proposed line for ember < 2.0 and get this error: Error while processing route: game params is not defined – rmcsharry May 04 '16 at 09:32
  • Ok I fixed that error by adding params to the function parameters, now I get another error: game reload is not defined – rmcsharry May 04 '16 at 09:43
  • Finally found the solution by reading this: http://discuss.emberjs.com/t/force-store-to-reload-data-from-api/4441/16 Need to pass the game.id from the games list template, not the full game model. Then had to use fetchById, not find. – rmcsharry May 04 '16 at 10:15