Fix references in V3 payloads
V3 API doesn't return any of the records more than 2 times. If a record is already included in the response any other occurences will be represented as a reference, ie. a hash with just an @href. Ember Data doesn't play nice with such references as it needs an id to identify a record. The code in this commit traverses payloads from V3 API and adds an id to each of the references that are present. For example a following payload: { "@href": "/build/1", "@type": "build" "id": 1, "state": "passed", "branch": { "@href": "/repo/1/branch/master", "name": "master", "lastBuild": { "@href": "/build/1" } } } Will be changed to: { "@href": "/build/1", "@type": "build" "id": 1, "state": "passed", "branch": { "@href": "/repo/1/branch/master", "name": "master", "lastBuild": { "@href": "/build/1", "id": 1 } } } In this case an "id" field was added to "branch.lastBuild" field.
This commit is contained in:
parent
e2a602a8af
commit
147ab06fcf
|
@ -1,6 +1,29 @@
|
||||||
import Ember from 'ember';
|
import Ember from 'ember';
|
||||||
import DS from 'ember-data';
|
import DS from 'ember-data';
|
||||||
|
|
||||||
|
var traverse = function(object, callback) {
|
||||||
|
if(!object) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(typeof(object) === 'object' && !Ember.isArray(object)) {
|
||||||
|
callback(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Ember.isArray(object)) {
|
||||||
|
for(let item of object) {
|
||||||
|
traverse(item, callback);
|
||||||
|
}
|
||||||
|
} else if(typeof object === 'object') {
|
||||||
|
for(let key in object) {
|
||||||
|
if(object.hasOwnProperty(key)) {
|
||||||
|
let item = object[key];
|
||||||
|
traverse(item, callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export default DS.JSONSerializer.extend({
|
export default DS.JSONSerializer.extend({
|
||||||
isNewSerializerAPI: true,
|
isNewSerializerAPI: true,
|
||||||
|
|
||||||
|
@ -38,6 +61,11 @@ export default DS.JSONSerializer.extend({
|
||||||
return attributes;
|
return attributes;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
normalizeResponse(store, primaryModelClass, payload, id, requestType) {
|
||||||
|
this._fixReferences(payload);
|
||||||
|
return this._super(...arguments);
|
||||||
|
},
|
||||||
|
|
||||||
normalizeArrayResponse(store, primaryModelClass, payload, id, requestType) {
|
normalizeArrayResponse(store, primaryModelClass, payload, id, requestType) {
|
||||||
let documentHash = {
|
let documentHash = {
|
||||||
data: null,
|
data: null,
|
||||||
|
@ -111,5 +139,44 @@ export default DS.JSONSerializer.extend({
|
||||||
} else {
|
} else {
|
||||||
return Ember.String.camelize(key);
|
return Ember.String.camelize(key);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_fixReferences(payload) {
|
||||||
|
let byHref = {}, href, records;
|
||||||
|
if(payload['@type']) {
|
||||||
|
// API V3 doesn't return all of the objects in a full representation
|
||||||
|
// If an object is present in one place in the response, all of the
|
||||||
|
// other occurences will be just references of a kind - they will just
|
||||||
|
// include @href property.
|
||||||
|
//
|
||||||
|
// I don't want to identify records by href in ember-data, so here I'll
|
||||||
|
// set an id and a @type field on all of the references.
|
||||||
|
//
|
||||||
|
// First we need to group all of the items in the response by href:
|
||||||
|
traverse(payload, (item) => {
|
||||||
|
if(href = item['@href']) {
|
||||||
|
if(records = byHref[href]) {
|
||||||
|
records.push(item);
|
||||||
|
} else {
|
||||||
|
byHref[href] = [item];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Then we can choose a record with an id for each href and put the id
|
||||||
|
// in all of the other occurences.
|
||||||
|
for(let href in byHref) {
|
||||||
|
records = byHref[href];
|
||||||
|
let recordWithAnId = records.find( (record) => record.id );
|
||||||
|
if(recordWithAnId) {
|
||||||
|
for(let record of records) {
|
||||||
|
record.id = recordWithAnId.id;
|
||||||
|
//record['@type'] = recordWithAnId['@type'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return payload;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user