dist/globals/ember-data.prod.js in ember-data-source-2.5.0.beta.3 vs dist/globals/ember-data.prod.js in ember-data-source-2.5.0.beta.4

- old
+ new

@@ -4,11 +4,11 @@ /*! * @overview Ember Data * @copyright Copyright 2011-2016 Tilde Inc. and contributors. * Portions Copyright 2011 LivingSocial Inc. * @license Licensed under MIT license (see license.js) - * @version 2.5.0-beta.3 + * @version 2.5.0-beta.4 */ var define, requireModule, require, requirejs; (function() { @@ -1791,59 +1791,44 @@ /** @module ember-data */ /** - Holds validation errors for a given record organized by attribute names. + Holds validation errors for a given record, organized by attribute names. - Every DS.Model has an `errors` property that is an instance of + Every `DS.Model` has an `errors` property that is an instance of `DS.Errors`. This can be used to display validation error messages returned from the server when a `record.save()` rejects. - For Example, if you had an `User` model that looked like this: + For Example, if you had a `User` model that looked like this: ```app/models/user.js import DS from 'ember-data'; export default DS.Model.extend({ username: attr('string'), email: attr('string') }); ``` - And you attempted to save a record that did not validate on the backend. + And you attempted to save a record that did not validate on the backend: ```javascript var user = store.createRecord('user', { username: 'tomster', email: 'invalidEmail' }); user.save(); ``` - Your backend data store might return a response with status code 422 (Unprocessable Entity) - and that looks like this. This response will be used to populate the error object. + Your backend would be expected to return an error response that described + the problem, so that error messages can be generated on the app. - ```javascript - { - "errors": [ - { - "detail": "This username is already taken!", - "source": { - "pointer": "data/attributes/username" - } - }, { - "detail": "Doesn't look like a valid email.", - "source": { - "pointer": "data/attributes/email" - } - } - ] - } - ``` + API responses will be translated into instances of `DS.Errors` differently, + depending on the specific combination of adapter and serializer used. You + may want to check the documentation or the source code of the libraries + that you are using, to know how they expect errors to be communicated. - For additional information on the error object, see the [JSON API spec](http://jsonapi.org/format/#error-objects). - Errors can be displayed to the user by accessing their property name to get an array of all the error objects for that property. Each error object is a JavaScript object with two keys: - `message` A string containing the error message from the backend @@ -1874,37 +1859,10 @@ {{message}} </div> {{/each}} ``` - The JSON API spec also allows for object level errors to be placed - in an object with pointer `data`. - - ```javascript - { - "errors": [ - { - "detail": "Some generic non property error message", - "source": { - "pointer": "data" - } - } - ] - } - ``` - - You can access these errors by using the `base` property on the errors - object. - - ```handlebars - {{#each model.errors.base as |error|}} - <div class="error"> - {{error.message}} - </div> - {{/each}} - ``` - @class Errors @namespace DS @extends Ember.Object @uses Ember.Enumerable @uses Ember.Evented @@ -5590,11 +5548,16 @@ }); }; BelongsToReference.prototype.value = function () { var inverseRecord = this.belongsToRelationship.inverseRecord; - return inverseRecord && inverseRecord.record; + + if (inverseRecord && inverseRecord.record) { + return inverseRecord.record; + } + + return null; }; BelongsToReference.prototype.load = function () { var _this2 = this; @@ -6714,12 +6677,12 @@ }; BelongsToRelationship.prototype.setCanonicalRecord = function (newRecord) { if (newRecord) { this.addCanonicalRecord(newRecord); - } else if (this.inverseRecord) { - this.removeCanonicalRecord(this.inverseRecord); + } else if (this.canonicalState) { + this.removeCanonicalRecord(this.canonicalState); } this.setHasData(true); this.setHasLoaded(true); }; @@ -10942,10 +10905,28 @@ should use the REST adapter. This adapter is designed around the idea that the JSON exchanged with the server should be conventional. + ## Success and failure + + The REST adapter will consider a success any response with a status code + of the 2xx family ("Success"), as well as 304 ("Not Modified"). Any other + status code will be considered a failure. + + On success, the request promise will be resolved with the full response + payload. + + Failed responses with status code 422 ("Unprocessable Entity") will be + considered "invalid". The response will be discarded, except for the + `errors` key. The request promise will be rejected with a `DS.InvalidError`. + This error object will encapsulate the saved `errors` value. + + Any other status codes will be treated as an "adapter error". The request + promise will be rejected, similarly to the "invalid" case, but with + an instance of `DS.AdapterError` instead. + ## JSON Structure The REST adapter expects the JSON returned from your server to follow these conventions. @@ -11019,10 +11000,28 @@ "occupation": "President" } } ``` + ### Errors + + If a response is considered a failure, the JSON payload is expected to include + a top-level key `errors`, detailing any specific issues. For example: + + ```js + { + "errors": { + "msg": "Something went wrong" + } + } + ``` + + This adapter does not make any assumptions as to the format of the `errors` + object. It will simply be passed along as is, wrapped in an instance + of `DS.InvalidError` or `DS.AdapterError`. The serializer can interpret it + afterwards. + ## Customization ### Endpoint path customization Endpoint paths can be prefixed with a `namespace` by setting the namespace @@ -13651,10 +13650,13 @@ normalize: function (modelClass, resourceHash) { var data = null; if (resourceHash) { this.normalizeUsingDeclaredMapping(modelClass, resourceHash); + if (_ember.default.typeOf(resourceHash.links) === 'object') { + this.normalizeUsingDeclaredMapping(modelClass, resourceHash.links); + } data = { id: this.extractId(modelClass, resourceHash), type: modelClass.modelName, attributes: this.extractAttributes(modelClass, resourceHash), @@ -14310,13 +14312,14 @@ Example ```app/serializers/post.js import DS from 'ember-data'; export default DS.JSONSerializer.extend({ extractMeta: function(store, typeClass, payload) { - if (payload && payload._pagination) { - store.setMetadataFor(typeClass, payload._pagination); + if (payload && payload.hasOwnProperty('_pagination')) { + let meta = payload._pagination; delete payload._pagination; + return meta; } } }); ``` @method extractMeta @@ -14331,15 +14334,63 @@ return meta; } }, /** - `extractErrors` is used to extract model errors when a call is made - to `DS.Model#save` which fails with an `InvalidError`. By default + `extractErrors` is used to extract model errors when a call + to `DS.Model#save` fails with an `InvalidError`. By default Ember Data expects error information to be located on the `errors` property of the payload object. - Example + This serializer expects this `errors` object to be an Array similar + to the following, compliant with the JSON-API specification: + ```js + { + "errors": [ + { + "detail": "This username is already taken!", + "source": { + "pointer": "data/attributes/username" + } + }, { + "detail": "Doesn't look like a valid email.", + "source": { + "pointer": "data/attributes/email" + } + } + ] + } + ``` + The key `detail` provides a textual description of the problem. + Alternatively, the key `title` can be used for the same purpose. + The nested keys `source.pointer` detail which specific element + of the request data was invalid. + Note that JSON-API also allows for object-level errors to be placed + in an object with pointer `data`, signifying that the problem + cannot be traced to a specific attribute: + ```javascript + { + "errors": [ + { + "detail": "Some generic non property error message", + "source": { + "pointer": "data" + } + } + ] + } + ``` + When turn into a `DS.Errors` object, you can read these errors + through the property `base`: + ```handlebars + {{#each model.errors.base as |error|}} + <div class="error"> + {{error.message}} + </div> + {{/each}} + ``` + Example of alternative implementation, overriding the default + behavior to deal with a different format of errors: ```app/serializers/post.js import DS from 'ember-data'; export default DS.JSONSerializer.extend({ extractErrors: function(store, typeClass, payload, id) { if (payload && typeof payload === 'object' && payload._problems) { @@ -15066,11 +15117,11 @@ payloadKeyFromModelName: function(modelName) { return Ember.String.dasherize(modelName); } }); ``` - Given a `TacoParty' model, calling `save` on a tacoModel would produce an outgoing + Given a `TacoParty` model, calling `save` on it would produce an outgoing request like: ```js { "taco-party": { "id": "1", @@ -15255,10 +15306,10 @@ */ deserialize: null }); }); define("ember-data/version", ["exports"], function (exports) { - exports.default = "2.5.0-beta.3"; + exports.default = "2.5.0-beta.4"; }); define("ember-inflector", ["exports", "ember", "ember-inflector/lib/system", "ember-inflector/lib/ext/string"], function (exports, _ember, _emberInflectorLibSystem, _emberInflectorLibExtString) { _emberInflectorLibSystem.Inflector.defaultRules = _emberInflectorLibSystem.defaultRules; _ember.default.Inflector = _emberInflectorLibSystem.Inflector;