Skip to content

Instantly share code, notes, and snippets.

@marbemac
Created September 8, 2014 21:08
Show Gist options
  • Save marbemac/06c5040e4d71694f07b3 to your computer and use it in GitHub Desktop.
Save marbemac/06c5040e4d71694f07b3 to your computer and use it in GitHub Desktop.
Ember.js custom serializer for consistent JSON root
// API return format is as so:
// {
// data: [
// {
// name: 'foo'
// },
// {
// name: 'bar'
// }
// ]
// }
// Ember expects:
// {
// posts: [
// {
// name: 'foo'
// },
// {
// name: 'bar'
// }
// ]
// }
import Ember from 'ember';
import DS from "ember-data";
export default DS.RESTSerializer.extend({
// Custom json root. The API returns objects in the "data" key.
// We need to re-assign it to the singular version of the model name.
// So {data: {name: foo}} becomes {post: {name: foo}}
extractSingle: function(store, primaryType, rawPayload, recordId) {
var typeKey = primaryType.typeKey;
payload[typeKey] = payload['data'];
delete payload['data'];
return this._super(store, primaryType, rawPayload, recordId);
},
// Custom json root. The API returns objects in the "data" key.
// We need to re-assign it to the plural version of the model name.
// So {data: [{post1}, {post2}]} becomes {posts: [{post1},{post2}]}
extractArray: function(store, primaryType, payload) {
var pluralTypeKey = Ember.Inflector.inflector.pluralize(primaryType.typeKey);
payload[pluralTypeKey] = payload['data'];
delete payload['data'];
return this._super(store, primaryType, payload);
}
});
@RobbieMcKinstry
Copy link

Thanks for this! It seems like the Ember REST adaptor doesn't follow the JSON:API spec as closely as I thought... :\

@camsjams
Copy link

Thanks!

I believe this should be using rawPayload instead of payload:

    extractSingle: function(store, primaryType, rawPayload, recordId) {
            var typeKey = primaryType.typeKey;
            payload[typeKey] = payload['data'];
            delete payload['data'];

            return this._super(store, primaryType, rawPayload, recordId);
    },

@jkeen
Copy link

jkeen commented Sep 12, 2015

This is what you need for Ember Data 2.0

import DS from 'ember-data';
export default DS.RESTSerializer.extend({
  // Custom json root. The API returns objects in the "data" key.
    // We need to re-assign it to the singular version of the model name.
    // So {data: {name: foo}} becomes {post: {name: foo}}

    normalizeSingleResponse: function(store, primaryModelClass, payload, id, requestType) {
        var typeKey = primaryModelClass.modelName;
        payload[typeKey] = payload['data'];
        delete payload['data'];

        return this._normalizeResponse(store, primaryModelClass, payload, id, requestType, true);
    },
    // Custom json root. The API returns objects in the "data" key.
    // We need to re-assign it to the plural version of the model name.
    // So {data: [{post1}, {post2}]} becomes {posts: [{post1},{post2}]}
    normalizeArrayResponse: function(store, primaryModelClass, payload, id, requestType) {
        var pluralTypeKey = Ember.Inflector.inflector.pluralize(primaryModelClass.modelName);
        payload[pluralTypeKey] = payload['data'];
        delete payload['data'];

        return this._normalizeResponse(store, primaryModelClass, payload, id, requestType, false);
    }
});

@brunoocasali
Copy link

For ember data 3.24:

import RESTSerializer from '@ember-data/serializer/rest';

export default class SubscriptionSerializer extends RESTSerializer {
  normalizeSingleResponse(store, primaryModelClass, payload, id, requestType) {
    const typeKey = primaryModelClass.modelName;

    // My third party api does not respond with a root level key.
    let hash = { [typeKey]: payload };

    return super._normalizeResponse(store, primaryModelClass, hash, id, requestType, true);
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment