queryrecord jsonapiadapter ember all ember.js ember-data ember-cli json-api

ember.js - jsonapiadapter - Manejo de errores con el(ahora predeterminado) adaptador Ember Data JSON-API



jsonapiadapter ember (1)

Estoy usando Ember 1.13.7 y Ember Data 1.13.8, que por defecto usan el estándar JSON-API para formatear las cargas útiles enviadas y recibidas desde la API.

Me gustaría utilizar el manejo de errores integrado de Ember Data para mostrar al usuario los campos rojos de "error". He formateado mis respuestas de error de API según el estándar JSON-API, p. Ej.

{"errors":[ { "title":"The included.1.attributes.street name field is required.", "code":"API_ERR", "status":"400", } ]}

y cuando intento guardar mi modelo, la devolución de llamada de error se está ejecutando correctamente. Si miro dentro del Inspector de ascuas, puedo ver que el valor "isError" del modelo está establecido en verdadero, pero no puedo ver cómo se supone que Ember Data sabe qué campo dentro del modelo es el que está en estado de error. Veo en las páginas oficiales de JSON-API ( http://jsonapi.org/format/#errors ) que puede incluir un objeto "fuente" dentro de la respuesta de error:

fuente: un objeto que contiene referencias a la fuente del error, que incluye opcionalmente cualquiera de los siguientes miembros:

puntero: un puntero JSON [RFC6901] a la entidad asociada en el documento de solicitud [por ejemplo, "/ data" para un objeto de datos primario, o "/ data / atributos / título" para un atributo específico].

parámetro: una cadena que indica qué parámetro de consulta causó el error.

pero, ¿es esto lo que debería hacer para decirle a Ember Data qué campos debe marcar como en estado de error?

Si alguien puede ayudar a arrojar algo de luz sobre esto, estaría agradecido.

Gracias.


Tenga en cuenta que la respuesta a continuación se basa en las siguientes versiones:

DEBUG: ------------------------------- ember.debug.js:5442DEBUG: Ember : 1.13.8 ember.debug.js:5442DEBUG: Ember Data : 1.13.9 ember.debug.js:5442DEBUG: jQuery : 1.11.3 DEBUG: -------------------------------

Desafortunadamente, la documentación de manejo de errores está dispersa en este momento, ya que la forma en que maneja los errores para los diferentes adaptadores (Active, REST, JSON) es un poco diferente.

En su caso, desea manejar los errores de validación de su formulario, lo que probablemente significa errores de validación. El formato para los errores según lo especificado por la API JSON se puede encontrar aquí: http://jsonapi.org/format/#error-objects

Notarás que la API solo especifica que los errores se devuelven en una matriz de nivel superior con clave de errors y todos los demás atributos de error son opcionales. Aparentemente, todo lo que requiere la API JSON es lo siguiente:

{ "errors": [ {} ] }

Por supuesto, eso realmente no hará nada, por lo que para que los errores funcionen de fábrica con Ember Data y el adaptador JSONAPIA, deberá incluir como mínimo el atributo de detail y el atributo de source/pointer . El atributo de detail es lo que se establece como mensaje de error y el atributo de source/pointer permite que Ember Data descubra qué atributo en el modelo está causando el problema. Por lo tanto, un objeto de error de API JSON válido según lo requerido por Ember Data (si está utilizando JSONAPI, que ahora es el predeterminado) es algo como esto:

{ "errors": [ { "detail": "The attribute `is-admin` is required", "source": { "pointer": "data/attributes/is-admin" } } ] }

Tenga en cuenta que los detail no son plurales (un error común para mí) y que el valor de la source/pointer no debe incluir una barra inclinada hacia adelante y el nombre del atributo debe ser discontinuo.

Finalmente, debe devolver su error de validación utilizando el Código HTTP 422 que significa "Entidad no procesable". Si no devuelve un código 422 , de forma predeterminada, Ember Data devolverá un AdapterError y no establecerá los mensajes de error en el hash de errors del modelo. Esto me mordió por un tiempo porque estaba usando el Código HTTP 400 (Solicitud incorrecta) para devolver errores de validación al cliente.

La forma en que ember data diferencia los dos tipos de errores es que un error de validación devuelve un objeto InvalidError ( emberjs.com/api/data/classes/DS.InvalidError.html ). Esto hará que se establezca el hash de errors en el modelo, pero no establecerá el indicador isError en verdadero (no estoy seguro de por qué es así, pero está documentado aquí: http://emberjs.com/api/data/classes/DS.Model.html#property_isError ). Por defecto, un código de error HTTP que no sea 422 dará como resultado que se AdapterError un AdapterError y que el indicador isError establezca en true . En ambos casos, se llamará al controlador de rechazo de la promesa.

model.save().then(function(){ // yay! it worked }, function(){ // it failed for some reason possibly a Bad Request (400) // possibly a validation error (422) }

De manera predeterminada, si el código HTTP devuelto es 422 y tiene el formato de error JSON API correcto, puede acceder a los mensajes de error accediendo al hash de errores del modelo donde las claves hash son sus nombres de atributos. El hash está tecleado en el nombre del atributo en el formato camelcase.

Por ejemplo, en nuestro ejemplo de error json-api anterior, si hay un error en is-admin accedería a ese error de esta manera:

model.get(''errors.isAdmin'');

Esto devolverá una matriz que contiene objetos de error donde el formato es así:

[ { "attribute": "isAdmin", "message": "The attribute `is-admin` is required" } ]

Esencialmente, los detail se asignan al message y la source/pointer se asigna al attribute . Se devuelve una matriz en caso de que tenga múltiples errores de validación en un solo atributo (la API JSON le permite devolver múltiples errores de validación en lugar de devolver solo la primera validación que falla). Puede usar los valores de error directamente en una plantilla como esta:

{{#each model.errors.isAdmin as |error|}} <div class="error"> {{error.message}} </div> {{/each}}

Si no hay errores, lo anterior no mostrará nada, por lo que funciona bien para hacer mensajes de validación de formularios.

Si su API no usa el código HTTP 422 para errores de validación (por ejemplo, si usa 400 ), puede cambiar el comportamiento predeterminado del adaptador JSONAPIA anulando el método handleResponse en su adaptador personalizado. Aquí hay un ejemplo que devuelve un nuevo objeto InvalidError para cualquier código de estado de respuesta HTTP que sea 400 .

import DS from "ember-data"; import Ember from "ember"; export default DS.JSONAPIAdapter.extend({ handleResponse: function(status, headers, payload){ if(status === 400 && payload.errors){ return new DS.InvalidError(payload.errors); } return this._super(...arguments); } });

En el ejemplo anterior, verifico si el estado HTTP es 400 y me aseguro de que exista una propiedad de errores. Si es así, creo un nuevo DS.InvalidError y lo devuelvo. Esto dará como resultado el mismo comportamiento que el comportamiento predeterminado que espera un código de estado HTTP 422 (es decir, su error de API JSON se procesará y el mensaje se colocará en el hash de errores en el modelo).

¡Espero que ayude!