Ember-data find entry by id, as well as additional parameters?

In Ember docs, I found that find () supports searching 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 have to find by id and pass an additional parameter to request all fields that will be included in the response (some are omitted by default), for example:

 this.store.find('post', 1); // => GET /posts/1?include=all 

I tried to do it as follows:

 this.get('store').find('post', params.post_id, { include : 'all' }); 

But my options were ignored.

This seems like a pretty basic option, so I have to skip something ...

How can i do this?

+9
javascript ember-data
source share
6 answers

You may have found a workaround issue at the moment, but the way to use it is to use adapterOptions in the options argument.

So release:

  • When you select a model (i.e. a route), configure the custom argument you want. In your case, enable. This happens as follows:

     //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 adapter to configure 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); } }); 

UPDATE 1:

In newer versions of ember-data (> = 2.4.0), you can do this out of the box by calling store.findRecord('post', {include: 'all'});

+3
source share

PhStoned code works, but causes errors if adapterOptions attributes are empty. 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); } } }); 
+2
source share

You can use queryRecord instead of find if you want to pass additional parameters to the backend.

 this.store.queryRecord('post', { id: params.post_id, include: 'all' }).then(function(data) { // do something with `data` }); 
+1
source share

Rodrigo Marrocim’s answer didn’t help me. So I came to the next decision
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); } } }); 

:

 this.get('store').findRecord('modelName', id, { adapterOptions: { include: 'all' } }); 
+1
source share

My suggestion is to try using the query function, not the find function. This will allow you to request 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` }); 
0
source share

It may be useful to use ajax with an 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 is 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)); } }); } }); 
0
source share

All Articles