Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ember-data find record by id and also additional parameters?

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?

like image 200
Edy Bourne Avatar asked Jul 14 '14 21:07

Edy Bourne


People also ask

How do I use Ember data?

Ember comes with a data management library called Ember Data to help deal with persistent application data. Ember Data requires you to define the structure of the data you wish to provide to your application by extending DS. Model . import DS from 'ember-data'; export default DS.

What is store in Ember?

One way to think about the store is as a cache of all of the records that have been loaded by your application. If a route or a controller in your app asks for a record, the store can return it immediately if it is in the cache.


2 Answers

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' }
});
like image 176
zhisme Avatar answered Oct 21 '22 20:10

zhisme


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:

  1. 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' }
        });
      }
    });
    
  2. 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);
        }
    });
    

UPDATE 1:

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

like image 43
Rodrigo Marroquim Avatar answered Oct 21 '22 18:10

Rodrigo Marroquim