I'm trying to write a route that need access to its parent's model. I use this.modelFor()
, but when I do that, the parent's model isn't completely loaded, so all its properties contains null
.
This is the router, with two dynamic segments:
MGames.Router.map(function () {
this.resource('games', function () {
this.resource ('game', {path: '/:game_id'}, function () {
this.resource('board', {path: '/boards/:board_id'});
});
});
});
This is my GameRoute, who works perfectly:
MGames.GameRoute = Ember.Route.extend ({
model: function (params) {
return MGames.Game.find(params.game_id);
}
});
And finally this is the child route, who need access to the Game model, and this is what I wrote. But no matters what I do, the console.log()
always prints null
. If I check the game
variable, the isLoad
property is always null:
MGames.BoardRoute = Ember.Route.extend ({
model: function (params) {
var game = this.modelFor ('game');
console.log (game.get("id"));
return MGames.Board.find(game.get("id"), params.board_id);
}
});
Am I doing something wrong, or (as I suspect) I'm missing some Ember concept?
This part of your code looks good. Your assumptions are correct in that, the nested route should get the model of the parent via modelFor
.
I suspect your find method is the source of the bug. I looked at your previous question, and I'm assuming the same Game.find
is used here(?)
The problem is to do with Promises
. Ember's router understands the async nature of the model
hook. But it relies on you returning a Promise
to do it's work. Currently you are using the jQuery promise but returning the game
object immediately in it's uninitialized state. The query loads from the server but the model()
hook is assumed to have resolved before that happens.
You want to directly return the jQuery Promise
from your model
hook + Do the parsing in the first then
and return that as the result.
Here's your modified Game.find
. Same principles apply to the other finders.
find: function (game, board) {
url = [MGames.GAMES_API_URL];
url.push ('games');
url.push (game);
url.push ('boards');
url.push (board);
url = url.join('/');
return $.getJSON(url)
.then(function(response) {
var game = MGames.Game.create({isLoaded: false});
game.setProperties(response);
game.set('isLoaded', true);
return game;
});
}
Note that, the game object is returned as is. Ember understands that when the promise is resolved(by returning anything other than a promise), that result is the model for the model()
hook. This game
object is the model that will be now be available in modelFor
in the nested route.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With