Why don't nested resources in Ember.js preserve the params hash? - ember.js

Given the following Ember.js application (using Ember 1.0.0.rc.6.1 and Ember Data 0.13):
App = Ember.Application.create({ LOG_TRANSITIONS: true });
App.Store = DS.Store.extend();
App.Router.map(function() {
this.resource('promotions', function() {
this.resource('promotion', { path: '/:promotion_id' }, function() {
this.resource('entrants', function() {
this.resource('entrant', { path: '/:entrant_id' });
});
});
});
});
App.PromotionRoute = Ember.Route.extend({
model: function() {
return { id: 1, name: 'My Promotion' };
}
});
App.EntrantsIndexRoute = Ember.Route.extend({
model: function(params) {
console.warn('EntrantsIndexRoute', '\nparams:', params, '\nparams.promotion_id:', params.promotion_id, '\narguments:', arguments);
console.log('params should be:', { promotion_id: 1 });
console.log('The queried URL should be:', '/entrants?promotion_id=1');
return App.Entrant.find({promotion_id: params.promotion_id});
}
});
App.Entrant = DS.Model.extend({
name: DS.attr('string')
});
If you enter the url #/promotions/1/entrants, which should be a nested resource, the params is an empty object. How can I access promotion_id there? JSFiddle here, take a look at the console after clicking on "Click me": http://jsfiddle.net/Kerrick/4GufZ/

While you can't access the dynamic segments of the parent route, you still can retrieve the model for the parent route and get its ID, like this:
App.EntrantsIndexRoute = Ember.Route.extend({
model: function() {
var promotion_id = this.modelFor('promotion').id;
return App.Entrant.find({ promotion_id: promotion_id });
}
});
Or, if there is a has-many relation between promotion and entrants, you even might do:
App.EntrantsIndexRoute = Ember.Route.extend({
model: function() {
return this.modelFor('promotion').get('entrants');
}
});

Try this code:
App.EntrantsIndexRoute = Ember.Route.extend({
model: function() {
var promotion_id = this.modelFor('promotion').query.promotion_id;
return App.Entrant.find({ promotion_id: promotion_id });
}
});

Related

Set multiple data with Ember and make it persist on Firebase

I am trying to set data from two models (that has hasMany & belongsTo relationship) and save them to firebase.
'list' data ends up being saved to firebase but not user data.
I think I'm doing something wrong at step 3. I'd appreciate your help!
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
return this.store.find('list');
},
actions: {
createList: function() {
var newListTitle = this.controllerFor('lists').get('newListTitle');
var username = this.get('session.user.displayName');
alert(this.get('session.user.displayName'));
if (Ember.isBlank(newListTitle)) { return false; }
//1
var list = this.store.createRecord('list', {
title: newListTitle,
user: username,
});
//2
this.controllerFor('lists').set('newListTitle', '');
var _this = this;
//3
list.save().then(function(list) {
user.get('lists').addObject(list);
user.save();
_this.transitionTo('lists.show', list); //4
});
}
}
});
Restructured your adding logic as well as user defined models, also modified your route, which could look like this in Edit and View mode. Meaning you can have more than one item returned from "model".
// Update models
App.List = DS.Model.extend({
value: DS.attr('string')
});
App.User = DS.Model.extend({
name: DS.attr('string')
});
App.UserLists = DS.Model.extend({
user: DS.belongsTo('user'),
list: DS.belongsTo('list')
});
export default Ember.Route.extend({
LIST:SHOW ROUTE
model: function(params) {
var store = this.get('store');
var userPromise = store.find('user', params.id);
return Ember.RSVP.hash({
user: userPromise,
userList : userPromise.then(function(user) {
return store.find(userList, { WhereUserIdIs : user.get('id') })
});
});
},
actions: {
createList: function() {
var self = this;
var failure = function(reason) {
// handle stuff
};
var list = this.store.createRecord('list', {
title: this.get('title'),
});
var user = this.get('user');
var usersList = store.createRecord('userList', {
'user': user,
'list': list
});
list.save().then(function(list) {
user.save().then(function() {
userList.save().then(function() {
self.transitionTo('lists.show', list.get('id'));
}, failure);
}, failure);
}, failure);
}
});

Save record of model is not working in ember-data 1.0.0-beta.3?

What I have done -
Model -
App.Book = DS.Model.extend({
book_name: DS.attr('string'),
edition: DS.attr('string')
});
Router -
App.Router.map(function() {
this.resource('books', function() {
this.route('new');
});
});
App.BooksNewRoute = Ember.Route.extend({
model: function() {
return this.store.createRecord('book');
},
actions: {
save: function() {
this.modelFor('newBook').save();
}
}
});
Now Can anybody help me.. How to save data ?
I am getting error like
TypeError: this.modelFor(...) is undefined
this.modelFor('newBook').save();
It is hard to tell how the context of your action looks like.
But one option is to pass the object you want to save as a parameter like this {{action save myBook}}.
Then you action could look like this:
App.BooksNewRoute = Ember.Route.extend({
model: function() {
return this.store.createRecord('book');
},
actions: {
save: function(book) {
book.save();
}
}
});
I think this should work.
App.BooksNewRoute = Ember.Route.extend({
model: function() {
return this.store.createRecord('book');
},
actions: {
save: function() {
this.get('model').save();
}
}
});

How to fetch a ember model with a more complex url

I'm using EmberData and wonder how I can I fetch a model from path like this:
products/:id/comments
Considering that you are using the default RESTAdapter, this is one possible way — although I'm not sure if it's the best one:
App = Ember.Application.create();
App.ProductCommentsRoute = Ember.Route.extend({
model: function() {
var productId = this.controllerFor('product').get('model').get('id');
return App.Comment.find({ product_id: productId });
}
});
App.Router.map(function() {
this.resource('products', function() {
this.resource('product', { path: ':product_id' }, function() {
this.route('comments');
})
});
});

Using "needs" to createRecord in router with the need-object as property

I want to know how to create a model in the router with a property taken from the dependency given by the "needs"-function of the controller. I'm using ember-1.0.0-rc.3.
Here is how my application looks now, a little simplified:
App.LeagueAddMatchRoute = Ember.Route.extend({
model: function (params) {
var match = App.Match.createRecord({});
return match;
},
setupController: function (controller) {
controller.set('players', App.Player.find());
}
});
App.LeagueAddMatchController = Ember.ObjectController.extend({
needs: "league",
save: function () {
this.get('model').get('transaction').commit();
return this.transitionToRoute('leagues');
}
});
App.Router.map(function () {
this.resource('leagues', function () {
this.resource('league', { path: ':league_id' }, function () {
this.route('addMatch');
})
});
});
App.LeaguesRoute = Ember.Route.extend({
model: function () {
return App.League.find();
}
});
App.League = DS.Model.extend({
name: DS.attr('string'),
matches: DS.hasMany('App.Match')
});
App.Match = DS.Model.extend({
league: DS.belongsTo('App.League'),
p1: DS.belongsTo('App.Player', {inverse: 'p1matches'}),
p2: DS.belongsTo('App.Player', {inverse: 'p2matches'}),
p1Score: DS.attr('number'),
p2Score: DS.attr('number')
});
This is what I would want to accomplish:
App.LeagueAddMatchRoute = Ember.Route.extend({
model: function (params) {
var match = App.Match.createRecord({league: controller.league });
return match;
},
setupController: function (controller) {
controller.set('players', App.Player.find());
}
});
From inside a route you can access a different controller using:
this.controllerFor("theControllerIWant");
so you can do:
App.LeagueAddMatchRoute = Ember.Route.extend({
model: function (params) {
var match = App.Match.createRecord();
match.set('league', this.controllerFor("league"));
return match;
},
setupController: function (controller) {
controller.set('players', App.Player.find());
}
});
Hope it helps

Ember initializing route model with query

I am trying to initialize a Route's model with a DS query, as follows
App.Router.map(function() {
this.resource('post', { path: '/posts/:post_slug' });
});
App.PostsRoute = Ember.Route.extend({
model: function(params) {
var records = App.Post.find({ slug: params.post_slug });
return records.get('firstObject');
}
});
Here, i find a Post by its slug and set the first result as the route model. but since records is populated asynchronously, the model data is not set properly. What is the correct way to do this?
Solved this with Deferred pattern.
App.PostsRoute = Ember.Route.extend({
model: function(params) {
var records = App.Post.find({ slug: params.post_slug });
var promise = Ember.Deferred.create();
records.addObserver('isLoaded', function() {
promise.resolve(records.get('firstObject'));
});
return promise;
}
});
That should do that trick:
App.Router.map(function() {
this.resource('posts');
this.resource('post', { path: '/posts/:post_id' });
});
App.PostsRoute = Ember.Route.extend({
model: function() {
return App.Post.find();
}
});
App.PostRoute = Ember.Route.extend({
model: function(params) {
return App.Post.find(params.post_id);
}
});