How can ember-data search for a record using both an ID and extra criteria?

While exploring the Ember documentation, I learned that the find() method supports finding by id:

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

It also allows for searching with arbitrary parameters:

this.store.find('post', { name: "Peter" }); // => GET to /posts?name='Peter'

However, in my specific scenario, I need to search by id and include all fields in the response (some are normally omitted by default), like this:

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

I attempted to achieve this using the following code:

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

Unfortunately, my additional parameter was not recognized.

Since this seems like a fundamental use case, I must be overlooking something...

How can I successfully accomplish this task?

Answer №1

If you haven't already found a solution to the issue, one workaround is to utilize the adapterOptions within the options argument.

Here's what you can do:

  1. When fetching the model (such as in a route), specify the custom argument you need. For example, if you need to include certain data, you can do so 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. Retrieve this value within 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:

In newer versions of ember-data (>= 2.4.0), you can achieve this more easily by calling

store.findRecord('post', {include: 'all'});

Answer №2

Even though PhStoned's code functions correctly, it may lead to errors if the adapterOptions parameter is empty. Please find below an enhanced version of the code.

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);
    }
  }
});

Answer №3

If you need to send extra parameters to the backend, consider using queryRecord instead of find.

this.store.queryRecord('article', { id: params.article_id, include: 'all' }).then(function(result) {
  // perform actions with the returned `result`
});

Answer №4

After trying Rodrigo Marroquim's solution without success, I have found a different approach to solve the issue.
Using Ember version 2.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);
    }
  }
});

Example of usage:

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

Answer №5

Instead of using the find function, I recommend utilizing the query function for more flexibility in filtering. By doing so, you can apply multiple filters without limitations.

var storeData = this.get('dataStore');
storeData.query('blog', { 
    _id: params.blog_id,
    include : 'all'
 }).then(function(posts) {
      // Perform actions with the retrieved posts
});

Answer №6

Consider implementing the adapter with ajax for improved functionality:

const { getOwner } = Ember;
let customAdapter = getOwner(this).lookup('adapter:application');
customAdapter.ajax(
  adapter.buildURL(`posts/${id}`), 'GET', { data: { include: 'all' }
);

#> /posts/1?include=all

This alternative ajax approach offers even more advantages:

const { inject: { service } } = Ember;

export default Ember.Route.extend({
  ajaxService: service(),

  async model(params) {
    let id = params.id;

    return await this.get('ajaxService')
      .request(`/posts/${id}`, {
        data: { include: 'all' }
      }).then(({ post }) => {
        if (post) {
          return this.store.push(this.store.normalize('post', post));
        }
      });
  }
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Randomize elements with the click of a button

Every time the page refreshes, the words shuffle around. For instance, "May I# know# your name?" shuffles to "know May I your name". To display the correct sentence with "#" as "May I know your name?", click the SHUFFLE button to trigger the shuffling. HT ...

Does HTML store information in Access databases?

Currently facing an issue, but first let's take a look at what resources I have. Current Resources: • A DB File in ACCESS containing over 100 lines of data. • An HTML webpage with inputs corresponding to the fields in the ACCESS file. • My o ...

Upon receiving data from the Api, the data cannot be assigned to the appropriate datatype within the Angular Object

I am encountering an issue with the normal input fields on my page: https://i.stack.imgur.com/qigTr.png Whenever I click on the "+" button, it triggers an action which in turn calls a service class with simple JSON data. My intention is to set selectionC ...

What is the best way to retrieve the response from an Observable/http/async call in Angular?

My service returns an observable that makes an http request to my server and receives data. However, I am consistently getting undefined when trying to use this data. What could be causing this issue? Service: @Injectable() export class EventService { ...

Creating a specialized .toString() function for an array

When trying to create a custom .toString() method on the Array prototype, how can you access the actual array that the method is called on? This approach seems to work: Array.prototype.toString = () => 'custom'; "" + [1,2,3]; // 'custom ...

Using PHP and Ajax to retrieve a distinct string prior to executing a time-consuming script

It's a question that comes up often. In short, I want to display progress to the user while a lengthy script is running. This is my approach: store "progress" in mysql so that Ajax can access it (via PHP). "progress()" is the lengthy script being te ...

Turning JSON data into an HTML table dynamically using jQuery for every single attribute

I have successfully accessed the json response and now I am looking to convert it into tables. The code snippet below demonstrates how I am parsing data related to the weather of different cities. <!DOCTYPE html> <html> <head> & ...

Guidelines for queuing method calls using Vue.js

Is there a way to invoke a method using a queue system? Imagine having a method that makes API calls and can only handle 3 calls at once. If more than 3 calls are made from a component, the remaining ones should wait until one call finishes before proceedi ...

Tips for sending routeparams value to model window in AngularJS

In the current project, I am working on implementing a modal window for the edit screen functionality. The process involves displaying a list of items on the screen, from which users can select one row and then click on the modify button to open the edit s ...

I am puzzled as to why my ajax script is giving me a 404 error even though the URL appears to be correct

Even though it's not a cross-domain problem, Ajax is returning a 404 error code. In my TIZEN Web application project, I am trying to make an ajax request to a WebService that contains functions necessary for the project. Initially, the xhr.status was ...

Saving JSON data as a file on server

Currently, I am running a localhost website on my Raspberry Pi using Apache and I am seeking advice on how to export a JSON string to a file on the Raspberry Pi itself. While I do know how to export a file, I am unsure of how to send it to the Raspberry Pi ...

What steps should be taken once the idToken in Firebase has expired?

My code is utilizing the onAuthStateChanged function: this.unregisterAuthObserver = firebase.auth().onAuthStateChanged(user => { if (user) { user.getIdToken(true).then((idToken) => { console.log(user) ... }); } After the idT ...

The background failed to display (potentially due to a hovering function)

I encountered an issue with a div that has a background image. Upon loading the page, the background image fails to display initially. However, when I hover over the div and then move my mouse elsewhere (due to a specific function described below), the bac ...

Optimal techniques for leveraging CSS within Mui and Reactjs

Just starting out with mui, I'm currently working on styling CSS for mui components like so <Typography variant="h5" sx={{ fontWeight: "bold", color: "#1a759f", display: "flex", ...

Display a badge in the navbar on specific VueJS pages

I have embarked on the journey of creating a single page application using Vue 3, and I've encountered an interesting scenario where I want to display a badge in the navigation bar for specific pages. This is how my setup looks: // App.vue <templat ...

Divide the table header column "th" into two separate columns

Can someone assist me in achieving the output displayed in the image? I want to separate the header th into two lines like the blue line shown. I need two headers for a single td column. Please help, thank you. https://i.sstatic.net/SwILH.png <style& ...

JavaScript Issue with Click Sound Not Functioning

Hi there, I am struggling with a small script that is supposed to play audio when clicking an image but it doesn't seem to be working. Can anyone help me fix it? <img src="tupac.png" width="600" height="420" alt="" onclick="song.play()"/> < ...

Displaying the complete response on Angular is possible, but JSON only shows the full response

I'm currently working on a project, and my main concern is: how do I access the response from the first array when all arrays have identical attribute names like body? similar to this: console.log and screen Everything works fine on a simple JSON ser ...

Encountering an issue when deploying a project using node, webpack, express, and mysql to Heroku. The error message states: "Uncaught ReferenceError: regeneratorRuntime is not

I've been going around in circles ever since I started this project, and now the code is all over the place. This is my first time working on a node project without using a framework, and I'm starting to regret not choosing PHP. Anyway, here&apos ...

Guide on using Ajax and spring MVC to dynamically fill a modal form

One JSP page displays database results in a table on the browser, allowing users to edit or delete each row. I want to implement a feature where clicking the edit link fetches specific customer data from the database using Spring MVC and Hibernate, display ...