Skip to content

Commit b4022cd

Browse files
committed
Merge pull request #57 from pixelhandler/caching-changes-and-text-errors
Update cache handling for updates, remove event triggers after update
2 parents c107fcd + fec180b commit b4022cd

File tree

6 files changed

+34
-49
lines changed

6 files changed

+34
-49
lines changed

addon/adapters/application.js

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,7 @@ export default Ember.Object.extend(FetchMixin, Ember.Evented, {
148148
},
149149

150150
/**
151-
Patch an existing resource, sends a PATCH request. After promise is resolved
152-
the `didUpdateResource` event is triggered, given an error response a event
153-
`resourceError` is triggered. A resource may listen on its `service` reference.
151+
Patch an existing resource, sends a PATCH request.
154152
155153
@method updateResource
156154
@param {Resource} the resource instance to serialize the changed attributes
@@ -164,11 +162,7 @@ export default Ember.Object.extend(FetchMixin, Ember.Evented, {
164162
method: 'PATCH',
165163
body: JSON.stringify(json),
166164
update: true
167-
}).then(function(json) {
168-
this.trigger('didUpdateResource', json);
169-
}.bind(this)).catch(function(resp) {
170-
this.trigger('resourceError', resp);
171-
}.bind(this));
165+
});
172166
},
173167

174168
/**
@@ -190,9 +184,7 @@ export default Ember.Object.extend(FetchMixin, Ember.Evented, {
190184
return this.fetch(url, {
191185
method: 'PATCH',
192186
body: JSON.stringify(data)
193-
}).then(function(json) {
194-
this.trigger('didUpdateRelationship', json);
195-
}.bind(this));
187+
});
196188
},
197189

198190
/**

addon/mixins/fetch.js

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,23 @@ export default Ember.Mixin.create({
5050
let msg = 'The Service responded with a '+ resp.status +' error.';
5151
reject(new ServerError(msg, resp));
5252
} else if (resp.status >= 400) {
53-
resp.json().then(function(_resp) {
54-
let msg = 'The API responded with a '+ resp.status +' error.';
55-
reject(new ClientError(msg, _resp));
53+
resp.text().then(function(_resp) {
54+
let json, msg = 'The API responded with a '+ resp.status +' error.';
55+
try {
56+
json = JSON.parse(_resp);
57+
} catch (e) {
58+
Ember.Logger.error(e);
59+
json = { "errors": [ { "status": resp.status } ] };
60+
}
61+
reject(new ClientError(msg, json));
5662
});
5763
} else if (resp.status === 204) {
5864
resolve('');
5965
} else {
6066
return resp.json().then(function(json) {
6167
if (isUpdate) {
62-
_this.cacheUpdate({ meta: json.meta, data: json.data, headers: resp.headers });
6368
json.data = _this.serializer.transformAttributes(json.data);
69+
_this.cacheUpdate({ meta: json.meta, data: json.data, headers: resp.headers });
6470
resolve(json.data);
6571
} else {
6672
let resource = _this.serializer.deserialize(json);
@@ -99,8 +105,8 @@ export default Ember.Mixin.create({
99105
} else {
100106
let headers = _this._getAjaxHeaders(jqXHR);
101107
if (isUpdate) {
102-
_this.cacheUpdate({ meta: json.meta, data: json.data, headers: headers });
103108
json.data = _this.serializer.transformAttributes(json.data);
109+
_this.cacheUpdate({ meta: json.meta, data: json.data, headers: headers });
104110
resolve(json.data);
105111
} else {
106112
let resource = _this.serializer.deserialize(json);
@@ -116,7 +122,11 @@ export default Ember.Mixin.create({
116122
reject(new ServerError(msg, jqXHR.responseJSON || jqXHR.responseText));
117123
} else if (jqXHR.status >= 400) {
118124
msg = 'The API responded with a '+ jqXHR.status +' error.';
119-
reject(new ClientError(msg, jqXHR.responseJSON || jqXHR.responseText));
125+
let json = jqXHR.responseJSON;
126+
if (!json) {
127+
json = { "errors": [ { "status": jqXHR.status, "detail": jqXHR.responseText } ] };
128+
}
129+
reject(new ClientError(msg, json));
120130
} else {
121131
msg = (errorThrown) ? errorThrown : 'Unable to Fetch resource(s)';
122132
reject(new FetchError(msg, {

addon/mixins/service-cache.js

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -98,18 +98,20 @@ export default Ember.Mixin.create({
9898
if (!Array.isArray(resp.data) && typeof resp.data === 'object') {
9999
resp.data = [ resp.data ];
100100
}
101-
let index, id;
101+
let index, id, item, isResourceType;
102102
for (let i = 0; i < resp.data.length; i++) {
103103
id = resp.data[i].id || resp.data[i].get('id');
104104
index = ids.indexOf(id);
105-
if (resp.data[i].toString().indexOf('JSONAPIResource') > -1) {
106-
if (index === -1) {
107-
this.cache.data.pushObject(resp.data[i]);
108-
} else {
109-
this.cache.data.replaceContent(index, 1, resp.data[i]);
110-
}
105+
isResourceType = resp.data[i].toString().indexOf('JSONAPIResource') > -1;
106+
if (index === -1 && isResourceType) {
107+
this.cache.data.pushObject(resp.data[i]);
108+
} else if (isResourceType) {
109+
this.cache.data.replaceContent(index, 1, resp.data[i]);
110+
} else if (index > -1) {
111+
item = this.cache.data.findBy('id', id);
112+
item.didUpdateResource(resp.data[i]);
111113
}
112-
this.cacheControl(this.cache.data.findBy('id', id), resp.headers);
114+
this.cacheControl(item || this.cache.data.findBy('id', id), resp.headers);
113115
}
114116
},
115117

addon/models/resource.js

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -253,19 +253,8 @@ const Resource = Ember.Object.extend({
253253
}).volatile(),
254254

255255
/**
256-
Initialize events to communicate with the service object, listen for `didUpdateResource`
257-
258-
@method initEvents
259-
*/
260-
initEvents: Ember.on('init', function () {
261-
const service = this.get('service');
262-
if (service) {
263-
service.on('didUpdateResource', this, this.didUpdateResource);
264-
}
265-
}),
266-
267-
/**
268-
Handler for `didUpdateResource` event, resets private _attributes used for changed/previous tracking
256+
Sets all payload properties on the resource and resets private _attributes
257+
used for changed/previous tracking
269258
270259
@method didUpdateResource
271260
@param json the updated data for the resource

tests/unit/adapters/application-test.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -396,8 +396,8 @@ test('#fetch handles 4xx (Client Error) response status', function(assert) {
396396
sandbox.stub(window, 'fetch', function () {
397397
return Ember.RSVP.Promise.resolve({
398398
"status": 404,
399-
"json": function() {
400-
return Ember.RSVP.Promise.resolve({ errors: [ { code: 404 } ] });
399+
"text": function() {
400+
return Ember.RSVP.Promise.resolve("{ errors: [ { status: 404 } ] }");
401401
}
402402
});
403403
});
@@ -406,7 +406,7 @@ test('#fetch handles 4xx (Client Error) response status', function(assert) {
406406
promise.catch(function(error) {
407407
assert.ok(error.name, 'Client Error', '4xx response throws a custom error');
408408
assert.ok(Array.isArray(error.errors), '4xx error includes errors');
409-
assert.equal(error.errors[0].code, 404, '404 error code is in errors list');
409+
assert.equal(error.errors[0].status, 404, '404 error status is in errors list');
410410
done();
411411
});
412412
});

tests/unit/models/resource-test.js

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,6 @@ test('it has properties for changed/previous attributes', function(assert) {
5656
});
5757
});
5858

59-
test('it has methods for communication on an event bus with service', function(assert) {
60-
const resource = this.subject();
61-
let methods = Ember.String.w('initEvents didUpdateResource');
62-
methods.forEach(function (method) {
63-
assert.ok(typeof resource[method] === 'function', 'resource#' + method + ' is a function');
64-
});
65-
});
66-
6759
test('it needs a reference to an injected service object', function(assert) {
6860
const resource = this.subject();
6961
assert.ok(resource.get('service') === null, 'resource#service is null by default');

0 commit comments

Comments
 (0)