TL;DR: super call in normalizeArrayResponse returns JSON Api Format, while being passed the old JSON format to handle.
Long explanation start
I have a Rest server which returns a findAll request like this (say for example querying Accounts):
{
[
{
"id": "5",
"name": "name 1"
},
{
"id": "8",
"name": "name 1"
}
]
}
With the new Serializer and JSON Api format, you would have the normalizeArrayResponse
return a JSON Api format of the above request like this, in order to adhere to the format.
{
"data": [
{
"id": "5",
"type": "account",
"attributes": {
"name": "name 1"
},
"relationships": {}
},
{
"id": "8",
"type": "account",
"attributes": {
"name": "name 1"
},
"relationships": {}
}
],
"included": []
}
So for that, I would write my serializer something like this (mind the flag isNewSerializerAPI: true,
is being set).
import DS from 'ember-data';
export default DS.RESTSerializer.extend({
isNewSerializerAPI: true,
normalizeArrayResponse: function(store, primaryModelClass, payload, id, requestType) {
var normalizedRecords = [];
payload.map(function(record){
var id = record.id;
delete record.id;
var normalizedRecord = {
'type': primaryModelClass.modelName,
'id': id,
'attributes': record
};
normalizedRecords.push(normalizedRecord);
});
normalizedRecords = {data: normalizedRecords};
return normalizedRecords;
}
});
This mostly works, however the only problem is, because I return just the JSON document (not calling this._super
), there are no Transforms being applied, (I have other attributes next to name and Id on account, where some are custom, and need a transform).
I thought that simply changing return normalizedRecords;
with return this._super(store, primaryModelClass, normalizedRecords, id, requestType);
would do the trick, but here things get weird.
I was getting a bunch of errors, for example: where the hash data
was being singularized
, and there was no DS.Model
âDatumâ defined.
After looking through the source code, and trying to figure out how to either apply transforms to my JSON Api document, or have this._super
handle a JSON Api format properly, I managed to figure out that the payload
variable has to be in the old format, for it to work.
So when I normalized my JSON document to this:
{
"account": [
{
"id": "5",
"type": "account",
"name": "name 1"
},
{
"id": "8",
"type": "account",
"name": "name 1"
}
],
}
and using that as the payload attribute in my this._super
call in the normalizeArrayResponse
hook, everything worked, and my transforms were being applied.
And after debugging, I found out that for some reason, the this._super
returns my previous JSON document (in the old format), returns a valid JSON Api document (in the new format)
So the Serializer below normalizes my initial REST Response to the previous JSON-format (see format right above), and then the this._super
normalizes THAT to a valid JSON Api Document
import DS from 'ember-data';
export default DS.RESTSerializer.extend({
isNewSerializerAPI: true,
normalizeArrayResponse: function(store, primaryModelClass, payload, id, requestType) {
var normalizedRecords = [];
payload.map(function(record){
record.type = primaryModelClass.modelName;
normalizedRecords.push(record);
});
var obj = {};
obj[primaryModelClass.modelName] = normalizedRecords;
return this._super(store, primaryModelClass, obj, id, requestType);
}
});
The Serializer above, returns the json below, because the super call, changes the old format to the new:
{
"data": [
{
"id": "5",
"type": "account",
"attributes": {
"name": "name 1"
},
"relationships": {}
},
{
"id": "8",
"type": "account",
"attributes": {
"name": "name 1"
},
"relationships": {}
}
],
"included": []
}
I guess there must be a question now:
- How do I apply transforms without calling super?
- Am I supposed to call super?
- Why doesnt the super class work with the new format (even though the
isNewSerializerAPI
flag is correctly set? - Am I doing something horribly wrong?
Kind Regards, pjcarly