I am using ember appkit for a beginner ember project. I am working with an existing API and my model looks as such:
export default Ember.Route.extend({
model: function(){
return this.store.find('prequalification');
}
});
When the API call happens, the URL is pluralized, prequalifications. I am trying to configure the RestAdapter but not sure where in the code flow this should happen.
Thanks for any help
Irregular or uncountable pluralizations can be specified via Ember.Inflector.inflector:
Ember.Inflector.inflector.irregular('formula', 'formulae');
Ember.Inflector.inflector.uncountable('advice');
This will tell the REST adapter that requests for App.Formula requests should go to /formulae/1 instead of /formulas/1.
REF : http://emberjs.com/guides/models/the-rest-adapter/#toc_pluralization-customization
It happens in the RestAdapter, you're correct...
check the pathForType attribute out out:
https://github.com/emberjs/data/blob/v1.0.0-beta.6/packages/ember-data/lib/adapters/rest_adapter.js#L476
Their example is:
DS.RESTAdapter.reopen({
pathForType: function(type) {
var decamelized = Ember.String.decamelize(type);
return Ember.String.pluralize(decamelized);
};
});
Related
I have a backend that follows the JSON API specification.
In my Ember app, I do something like this:
model() {
return this.store.query('category', { filter: { forum: 'main' } });
}
This works well and the request sent to the server is GET /categories?filter[forum]=main. My app gets all the categories from the forum with ID main.
Now, instead of the previous request, I would like to make a GET /forums/main/categories from the model. How can this be done in Ember with Ember Data?
Here's something I tried with Ember AJAX:
ajax: Ember.inject.service(),
model() {
return Ember.RSVP.hash({
categories: this.get('ajax').request('/forums/main/categories'),
});
}
The request works and the correct data is returned from the server. But Ember Data just doesn't know about it and I can't use the model in my template. How can I make Ember AJAX work with Ember Data?
The Ember AJAX GitHub page proposes to write something like that:
import DS from 'ember-data';
import AjaxServiceSupport from 'ember-ajax/mixins/ajax-support';
export default DS.JSONAPIAdapter.extend(AjaxServiceSupport);
https://github.com/ember-cli/ember-ajax#usage-with-ember-data
But it doesn't seem to change anything.
Okay, /forums/main/categories looks a bit like a relationship link. Like forum is a model as well, and has a relationship categories. Is this right?
If yes, probably the best thing is to first fetch the forum and then the relationship. Maybe you already have the forum record? So something like this:
store.findRecord('forum', 'main').then(forum => forum.get('categories'));
However if you want to filter the categories based on a forum string, this is also possible. So basically you want to do this:
this.store.query('category', { filter: { forum: 'main' } });
But it should request /forums/main/categories instead of /categories?filter[forum]=main. This can be done with a custom adapter. Probably you just have to override urlForQuery:
urlForQuery(query, modelName) {
if(query.filter.forum)
const forum = query.filter.forum;
delete query.filter.forum;
return `/forums/${forum}/categories`
} else {
return this._super(...arguments);
}
},
I have this model:
App.Game = DS.Model.extend({
name: attr(),
uri: attr()
});
and this route:
App.GamesRoute = Ember.Route.extend({
model: function() {
return this.store.find('game');
}
});
This works fine, calls the backend server, and stores elements in the store (I've checked with Ember inspector). This is the json I return:
{"games":[{"id":"TicTacToe","name":"TicTacToe","uri":"http://localhost:10000/games/TicTacToe"}]}
Now I have this template for 'games' (snipped):
{{#each game in model}}
{{#link-to 'games.matchlist' game.id}}{{game.uri}}{{/link-to}}
This shows the URI for each game. Now in the games.matchlist route what I would like to do is to search in the store by the game_id received param and get the game URI. The reason is that the server doesn't follow RESTAdapter conventions, and I would like to make a custom AJAX query to that URI myself.
This doesn't work:
App.GamesMatchlistRoute = Ember.Route.extend({model: function(params) {
var store = this.store;
var game = store.find('game', params.game_id)
console.log(game);
console.log("URI: " + game.uri);
at this point, game is an object but it's not an instance of my model. It doesn't have a uri attribute. What am I doing wrong? I'm feeling that I'm missing something obvious.
If you want to get records without hitting the server and you know you already have it in the store, use this.store.getById('game', ID).
I'm on my mobile, but you need to create a GameAdapter and customize I believe the fetch function. Checkout the docs for adapters on the ember site and you should have your answer.
Your other option is to fetch the data from your server and use this.store.pushPayload(data).
Docs here: http://emberjs.com/api/data/classes/DS.Store.html#method_pushPayload
And the adapter docs here: http://emberjs.com/guides/models/customizing-adapters/
In 1.7 Ember should support Query Parameters. I have no problems using them in controller but I'd like to access them in Route, ideally in beforeModel hook but model hook would work as well.
The API docs mention a queryParam parameter for the beforeModel hook but if I try to use it, it is always undefined.
The Query Parameters guide seems to suggest that the query parameters should be accessible as a part of the first parameter to the model hook. But that is also undefined. See the code below for examples.
Is there a way to access the query parameters from Route?
Thank you for your help.
App.ApplicationRoute = Em.Route.extend({
beforeModel: function(transition, queryParams){
console.log(queryParams.test); //undefined at /?test=123
},
model: function(params){
console.log(params.test); //undefined at /?test=123
}
});
Pretty sure it's a bug, but you can access them in the meantime via the transition object:
App.ApplicationRoute = Em.Route.extend({
beforeModel: function(transition){
console.log(transition.queryParams.test);
}
}
By specifying the query params in the controller, params will contain them automatically
ApplicationController = Ember.Controller.extend({
queryParams: ['test'],
test: null
});
In the latest version of ember (2.12 at the time of writing this answer), queryParams can be accessed in the model hook as follows:
import Ember from 'ember';
export default Ember.Route.extend({
queryParams: {
test: ''
},
model(params) {
console.log(params.test);
},
});
Observe that now both dynamic segment and queryParams are accessible via the params object. Since params is not available in the beforeModel hook, this solution works on when you have to access the queryParams in the model hook.
In latest ember version you can get the value in Route as
import Ember from 'ember';
export default Ember.Route.extend({
beforeModel(params){
console.log(params.queryParams.test); //if the parameter contains test as the key
}
});
This works only if the locationType is auto in your environment.js file.
If you want to access in didTransition action,
didTransition: (queryParams) ->
console.log(#get('queryParams'))
I'm using ember-cli and trying to make some sense of the structure of the app and how it is all wired together. There are some differences in the main Ember guide docs and what I'm seeing in the ember-cli generated project. I understand the API's are moving fast so I just need to be pointed in the right direction.
In router.js I have the following:
Router.map(function() {
this.route('domains', {path: "/domains" });
});
Then I have models/domain.js
import DS from 'ember-data';
var Domain = DS.Model.extend({
name: DS.attr('string')
});
Domain.reopenClass({
FIXTURES: [
{ id: 1, name: 'User'},
{ id: 2, name: 'Address'}
]
});
export default Domain;
And I have routes/domains.js
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
return this.store.all('domain');
}
});
And finally ( I think ), I have templates/domains.hbs
<h1>Domains</h1>
{{#each}}
<p>{{name}}</p>
{{/each}}
Only the header is being rendered when I visit the http://localhost:4200/domains url. I'm using the ember chrome extension and I don't see any data coming back in the request. I'm not sure if it is a naming convention issue or what I'm doing wrong so any help is appreciated.
all just returns records that have already been found in the store. find will issue a request (in this case hitting the fixtures) and populate the store, and also return all of the records in the store.
this.store.find('domain');
The problem ended up being 2-fold. Kingpin2K was right in that I needed to use find instead of all. I also had to change the adapter to the following in adapters/application.js:
export default DS.FixtureAdapter.extend();
I'm using the ember-data last version with an important problem I 'm trying to solve.
The find function by id works perfect and the proper record is loaded into the Data Store so I can obtain the attributes that I want in the template for render them.
App.PostRoute = Ember.Route.extend({
model: function(params) {
return this.store.find('post', params.post_id);
}
});
On the other side, the findAll function doesn't work for me and the problem is Ember doesn't throw any error. In addition, Ember doesn't load any record and besides that I don't know how to iterate over the RecordArray returned in the template.
App.PostsRoute = Ember.Route.extend({
model: function() {
return this.store.find('post');
}
});
Any suggestions? Thanks for the help.
From your comment above, if your response looks like:
[
{"id":"1","attribute1":"value1", ...,"attributen": "valuen"},
{"id":"2","attribute1":"value1", ...,"attributen": "valuen"}
]
and you have not provided a custom serializer that modifies your response in extractArray(...), then data will not get processed because Ember Data expects something like:
{
"pluralizedModelName": [
{"id":"1","attribute1":"value1", ...,"attributen": "valuen"},
{"id":"2","attribute1":"value1", ...,"attributen": "valuen"}
]
}
See the Ember Data 1.0 specific code: https://github.com/emberjs/data/blob/master/TRANSITION.md#rest-adapter-and-serializer-configuration
How are you referencing the model in the template? Are you using the generated controller, or defining it yourself?
Also, the RecordArray should be automatically resolved by your Handlebars template. Try referencing {{#each}}. By default, your template will look for the property on the controller and if not found, bubble up to the model. If you can, create a JSBin (emberjs.jsbin.com) and we can collaborate with an example.
Edit: Also, are you using Fixture or Rest Adapter?