In the Ember docs I found that find() has support for finding by id:
this.store.find('post', 1); // => GET /posts/1
And also by passing arbitrary parameters:
this.store.find('post', { name: "Peter" }); // => GET to /posts?name='Peter'
But in my case I must find by id, and pass an additional parameter to request all fields to be included in the response (some are omitted by default), like so:
this.store.find('post', 1); // => GET /posts/1?include=all
I tried to do it this way:
this.get('store').find('post', params.post_id, { include : 'all' });
But my params were ignored.
This seems a fairly basic use case so I must be missing something...
How can I accomplish this?
You may have found a workaround the problem by now, but the way to go is to use the adapterOptions
on the options
argument.
So, let's go:
Where you fetch the model (ie a route), setup the custom argument you want. In your case, the include. It goes like this:
//file app/routes/post/edit.js import Ember from 'ember'; export default Ember.Route.extend({ model: function(params) { return this.store.findRecord('post', params.post_id, { adapterOptions: { include: 'all' } }); } });
Read this value inside the model's adapter to customize the ajax request:
//file app/adapters/post.js export default JSONAPIAdapter.extend({ findRecord: function(store, type, id, snapshot) { if (Em.get(snapshot, 'include')) { let url = this.buildURL(type.modelName, id, snapshot, 'findRecord'); let query = this.buildQuery(snapshot); return this.ajax(url, 'GET', { data: query }); } else { this._super(...arguments); } });
On the ember-data newer versions (>= 2.4.0) you can do it out of the box, by calling store.findRecord('post', {include: 'all'});
PhStoned's code works but would cause errors if adapterOptions is blank. Here is an improved version.
import Ember from 'ember';
import applicationAdapter from './application';
export default applicationAdapter.extend({
findRecord: function(store, type, id, snapshot) {
if (snapshot.adapterOptions)) {
let url = this.buildURL(type.modelName, id, snapshot, 'findRecord');
let query = {
include: Ember.get(snapshot.adapterOptions, 'include')
};
return this.ajax(url, 'GET', { data: query });
} else {
return this._super(...arguments);
}
}
});
You can use queryRecord instead of find if you want to pass additional params to backend.
this.store.queryRecord('post', { id: params.post_id, include: 'all' }).then(function(data) {
// do something with `data`
});
Rodrigo Marroquim answer didn't work for me. So I've come to the following solution
Ember v2.6.0
import Ember from 'ember';
import applicationAdapter from './application';
export default applicationAdapter.extend({
findRecord: function(store, type, id, snapshot) {
if (Ember.get(snapshot.adapterOptions, 'include')) {
let url = this.buildURL(type.modelName, id, snapshot, 'findRecord');
let query = {
include: Ember.get(snapshot.adapterOptions, 'include')
};
return this.ajax(url, 'GET', { data: query });
} else {
this._super(...arguments);
}
}
});
usage:
this.get('store').findRecord('modelName', id, {
adapterOptions: { include: 'all' }
});
My suggestion would be to try using the query function rather than the find function. This will allow you to query an unlimited number of filters.
var myStore = this.get('store');
myStore.query('post', {
_id: params.post_id,
include : 'all'
}).then(function(peters) {
// Do something with `peters`
});
May helpful to use ajax with adapter implementation here:
const { getOwner } = Ember;
let adapter = getOwner(this).lookup('adapter:application');
adapter.ajax(
adapter.buildURL(`posts/${id}`), 'GET', { data: { include: 'all' } }
);
#> /posts/1?include=all
This ajax solution even better:
const { inject: { service } } = Ember;
export default Ember.Route.extend({
ajax: service(),
async model(params) {
let id = params.id;
return await this.get('ajax')
.request(`/posts/${id}`, {
data: { include: 'all' }
}).then(({ post }) => {
if (post) {
return this.store.push(this.store.normalize('post', post));
}
});
}
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.