Shivam Sinha
Shivam Sinha

Reputation: 5150

Ember Data 1.13.5 RESTAdapter queryRecord

Hi according to the ember ds 1.13 release docs:

If your app is using the vanilla JSONSerializer or RESTSerializer, you will not have to make any changes, and your app will continue to work. The existing serializers have been updated in a backwards compatible way to return JSON API data to the store.

Currently I am the default RESTAdapter:

export default DS.RESTAdapter.extend({
    host: 'http://localhost:9990',    
    namespace: 'api/v1'
});

Which has a custom serailzer for the model:

export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
  attrs: {
    comments: { embedded: 'always' }
  }
});

When I attempt to use the new queryRecord method:

this.store.queryRecord('discussion',{ titleid: self.get('title_id')});

I get the following exception in the logs:

Error while processing route: title.index Assertion Failed: You tried to make a query but your adapter does not implement `queryRecord` Error: Assertion Failed: You tried to make a query but your adapter does not implement `queryRecord`
    at new Error (native)
    at Error.EmberError (http://localhost:4200/assets/vendor.js:25705:21)
    at Object._emberMetalCore.default.assert (http://localhost:4200/assets/vendor.js:15895:13)
    at ember$data$lib$system$store$$Service.extend.queryRecord (http://localhost:4200/assets/vendor.js:80502:15)
    at loadDiscussionModel (http://localhost:4200/assets/ui.js:2728:32)
    at renderTemplate (http://localhost:4200/assets/ui.js:2715:12)
    at _emberRuntimeSystemObject.default.extend.setup (http://localhost:4200/assets/vendor.js:37282:14)
    at Object.callHook (http://localhost:4200/assets/vendor.js:65078:38)
    at handlerEnteredOrUpdated (http://localhost:4200/assets/vendor.js:63868:12)
    at setupContexts (http://localhost:4200/assets/vendor.js:63836:9)

serializer/application.js

import DS from 'ember-data';
export default DS.RESTSerializer.extend({
  serialize: function(record) {
    return this._super(record, {includeId: true});
  },
  isNewSerializerAPI: true
});

Upvotes: 1

Views: 1269

Answers (2)

KGA
KGA

Reputation: 56

According to source code default adapter does not have an implementation for queryRecord method: https://github.com/emberjs/data/blob/e89732a5aefb6a81b46927da1c6f048f4aede85e/packages/ember-data/lib/system/adapter.js#L226

Nor it's defined in RESTAdapter, neither in new JSONAPIAdapter. To my mind, this is due to query requests are too specific for every project thus are hard to generalize.

Nevertheless documentation contains explanation and example of implementation: http://emberjs.com/api/data/classes/DS.Adapter.html#method_queryRecord By the way, there are two errors:

  • id shold be passed as 4th argument;
  • type.typeKey should be replaced with typeClass.modelName.

We prefer using simpler implementation in our own project:

export default DS.RESTAdapter.extend({
  ...
  queryRecord: function(store, type, query, id) {
    return this.ajax(this.buildURL(type.modelName, id, null, 'query', query), 'GET');
  }
});

You can replace id argument with null in buildUrl method if needed.

Update

I forgot to mention, that in ember-data 1.13.5 RESTAdapter's default urlForQuery implementation returns url without actual query parameters passed. So here's out implementation based on default _buildUrl method, with id replaced by query:

urlForQuery: function(query, modelName) {
  var url = [];
  var host = this.get('host');
  var prefix = this.urlPrefix();
  var path;

  if (modelName) {
    path = this.pathForType(modelName);
    if (path) {
      url.push(path);
    }
  } 


  if (prefix) {
    url.unshift(prefix);
  }

  url = url.join('/');
  if (!host && url && url.charAt(0) !== '/') {
    url = '/' + url;
  }

  if (query) {
    var queryParams = [];
    for(var paramName in query) {
      if(query.hasOwnProperty(paramName)) {
        queryParams.push(paramName + '=' + encodeURIComponent(query[paramName]))
      }
    }
    if(queryParams.length > 0) {
      url = url + '?' + queryParams.join('&');
    }
  }

  return url;
}

This method is in the same adapter as queryRecord from the original answer.

Upvotes: 4

Shivam Sinha
Shivam Sinha

Reputation: 5150

Adding isNewSerializerAPI: true to the all the relevant model Serializers worked to a certain degree (it removed the Error stated below). However the original error still occurrs.

Before due to an incorrect import the following Error in the console logs was not being displayed.

Error: Assertion Failed: is using the old serializer API and expects it collaborates with to do the same. Make sure to set isNewSerializerAPI: true in your custom serializers if you want to use the new Serializer API.

Also FYI according to the documentation this flag will not be required in Ember Data 2.0:

http://emberjs.com/blog/2015/06/18/ember-data-1-13-released.html

If you have customized your serializer, you should upgrade to Ember Data 1.13, check the upgrade guide to see if you need to make any changes, and then set a temporary flag on your Serializer: isNewSerializerAPI. This will opt you into the new serializer API. Once you are on the Ember Data 2.0 train, new Serializer API is the default one, and there is no need for a flag.

Upvotes: 0

Related Questions