Reputation: 6187
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?
Upvotes: 10
Views: 10360
Reputation: 990
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));
}
});
}
});
Upvotes: 0
Reputation: 1281
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);
}
}
});
Upvotes: 2
Reputation: 2800
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' }
});
Upvotes: 1
Reputation: 46
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 (i.e. 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'});
Upvotes: 3
Reputation: 662
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`
});
Upvotes: 1
Reputation: 81
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`
});
Upvotes: 0