2015-08-10 10 views
19

Używam Ember 1.13.7 i Ember Data 1.13.8, które domyślnie używają standardu JSON-API do formatowania ładunków wysłanych do i otrzymanych od API.Obsługa błędów za pomocą domyślnego adaptera JSON-API Ember Data

Chciałbym użyć wbudowanej obsługi błędów Ember Data, aby wyświetlić czerwone pola "błędu" formularza dla użytkownika. Sformatowałem odpowiedzi na błędy interfejsu API zgodnie ze standardem JSON-API, np.

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

Kiedy podejmuję próbę zapisania modelu, wywołanie zwrotne błędu jest wykonywane poprawnie. Jeśli zajrzę do Inspektora Ember, widzę, że wartość "isError" modelu jest ustawiona na wartość true, ale nie widzę, jak Ember Data ma wiedzieć, które pole w modelu jest tym, które znajduje się w stanie błędu? Widzę z oficjalnych stron JSON API (http://jsonapi.org/format/#errors), które można dołączyć „źródło” obiektu w odpowiedzi błędu:

źródło: obiekt zawierający odniesienia do źródła błędu, ewentualnie zawierającą którykolwiek z następujący element:

wskaźnik: wskaźnik JSON [RFC6901] do powiązanej jednostki w dokumencie żądania [np. "/ data" dla podstawowego obiektu danych lub "/ data/attributes/title" dla określonego atrybutu]. Parametr: ciąg znaków wskazujący, który parametr powodował błąd.

ale to jest to, co należy robić, aby powiedzieć Ember dane, które pola należy oznaczyć jako będące w stanie błędu?

Jeśli ktokolwiek może pomóc rzucić trochę światła na ten temat, będę wdzięczny.

Dzięki.

+0

Nadal mam problemy z błędami i nowym formatem interfejsu JSON API, ale zgodnie z tą stroną, należy podać właściwość 'source/pointer', która pasuje do nazwy właściwości z błędem. http://emberjs.com/api/data/classes/DS.InvalidError.html – Sarus

+0

Tak, znalazłem to w zeszłym tygodniu, ale nie miałem okazji go wypróbować. Dziękuję za odpowiedź. – danr1979

+0

Nie ma problemu, jeśli uda Ci się uzyskać wszystko działa, zaktualizuj swoje pytanie. Jestem pewien, że byłoby to pomocne dla wielu ludzi. (Wiem, że byłoby to pomocne dla mnie haha!) – Sarus

Odpowiedz

80

Uwaga poniżej odpowiedź opiera się na następujących wersjach:

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: ------------------------------- 

Błąd obsługi dokumentacji jest niestety rozproszone wokół w tej chwili jako sposób obsługi błędów dla różnych adapterów (aktywna, REST, JSON) są trochę inne.

W twoim przypadku chcesz obsłużyć błędy sprawdzania poprawności w formularzu, co prawdopodobnie oznacza błędy sprawdzania poprawności. Format błędów określonych przez API JSON można znaleźć tutaj: http://jsonapi.org/format/#error-objects

Zauważysz, że API określa jedynie, że błędy są zwracane w tablicy poziomu górnej zamocowanej przez errors i wszystkie inne atrybuty błędach są opcjonalne. Tak pozornie wszystko, JSON API wymaga to:

{ 
    "errors": [ 
    {} 
    ] 
} 

Oczywiście, że nie będzie tak naprawdę nic do błędów do pracy po wyjęciu z pudełka z Ember Danych oraz JSONAPIAdapter trzeba będzie zawierać co najmniej atrybut detail i atrybut source/pointer. Atrybut detail jest ustawiany jako komunikat o błędzie, a atrybut source/pointer umożliwia Ember Data wykrycie, który atrybut w modelu powoduje problem.Tak jak wymaga tego Ember dane (jeśli używasz JSONAPI który jest teraz domyślnym) aktualny błąd JSON API przedmiot jest coś takiego:

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

Zauważ, że nie jest w liczbie mnogiej detail (częstym błędem dla mnie) i że wartość dla source/pointer nie powinna zawierać początkowego ukośnika, a nazwa atrybutu powinna być dasherizowana.

Na koniec należy zwrócić błąd sprawdzania poprawności, używając kodu HTTP 422, co oznacza "Nieprzetworzony element". Jeśli nie zwrócisz kodu 422, domyślnie Ember Data zwróci wartość AdapterError i nie ustawi komunikatów o błędach na mieszaniu modelu z hasłem errors. Trochę mnie to przez chwilę, ponieważ użyłem kodu HTTP 400 (Bad Request), aby zwrócić błędy sprawdzania poprawności do klienta.

Sposób w jaki dane embera rozróżniają dwa typy błędów, polega na tym, że błąd sprawdzania poprawności zwraca obiekt InvalidError (http://emberjs.com/api/data/classes/DS.InvalidError.html). Spowoduje to ustawienie wartości mieszania errors w modelu, ale nie ustawi flagi isError na wartość true (nie wiesz, dlaczego tak jest, ale jest to udokumentowane tutaj: http://emberjs.com/api/data/classes/DS.Model.html#property_isError). Domyślnie kod błędu HTTP inny niż 422 spowoduje zwrócenie AdapterError i ustawienie flagi isError na true. W obu przypadkach zostanie wywołany program odrzucający obietnicę.

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

Domyślnie jeśli kod HTTP zwrócony jest 422 i masz poprawny format JSON API błędzie następnie można uzyskać dostęp do komunikatów o błędach poprzez dostęp błędy modelu za hash gdzie klawisze skrótu są Twoje nazwy atrybutów. Hash jest wpisany na nazwę atrybutu w formacie camelcase.

Na przykład, w naszym przykładzie powyżej błędu json-api, jeśli wystąpi błąd na is-admin swój byłby dostęp ten błąd tak:

model.get('errors.isAdmin'); 

ta zwróci tablicę zawierającą obiekty o błędach, gdzie format jest tak:

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

Zasadniczo detail jest odwzorowywany message i source/pointer jest odwzorowywany attribute. Tablica jest zwracana w przypadku wielu błędów sprawdzania poprawności dla pojedynczego atrybutu (JSON API pozwala zwracać wiele błędów sprawdzania poprawności zamiast zwracać tylko pierwszą walidację, aby niepowodzenie). Można użyć wartości błędów bezpośrednio w szablonie tak:

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

Jeśli nie ma błędów, to powyższe nie wyświetla niczego tak to działa dobrze robi dla wiadomości walidacji formularza.

jeśli API nie używa protokołu HTTP kod 422 za błędy walidacji (na przykład, jeżeli wykorzystuje 400), a następnie można zmienić domyślne zachowanie JSONAPIAdapter poprzez nadpisanie metody handleResponse w niestandardowym adaptera. Oto przykład, który zwraca nowy obiekt InvalidError dla dowolnego kodu stanu odpowiedzi HTTP, który jest 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); 
    } 
}); 

W powyższym przykładzie mam sprawdzić, czy stan HTTP jest 400 i upewniając własności błędy istnieje.Jeśli tak, to tworzę nowy DS.InvalidError i zwrócę to. Spowoduje to zachowanie takie samo jak zachowanie domyślne, które oczekuje, że kod stanu HTTP HTTP (tj. Twój błąd interfejsu API JSON zostanie przetworzony, a wiadomość zostanie umieszczona w mieszaniu błędów w modelu).

Nadzieję, że pomaga!

+0

Dobra odpowiedź! Teraz bardzo dobrze, dziękuję. – danr1979

+0

OK, błędy w atrybutach znajdujących się w powiązanych modelach to teraz mój problem. Widzę błędy w tych powiązanych modelach, wykonując model.errors.content lub model.errors.messages, ale jeśli chcę sprawdzić konkretny atrybut w powiązanym modelu, aby podświetlić błędy w polach, otrzymuję wartości null lub undefined. – danr1979

+1

Możesz zadać jeszcze jedno pytanie z większą ilością szczegółów dotyczących konfiguracji swoich modeli, sposobu zapisywania modelu i odpowiedzi, którą odsyłasz? Nie próbowałem jeszcze używać relacji, więc nie mogę tego łatwo wypróbować na własnym projekcie. – Sarus