2013-04-10 9 views
13

Sto costruendo un'app che è stata progettata come un'app server Rails che fornisce API RESTful al client. Il server Rails utilizza RABL. Il client è un client Angular JS che esegue chiamate $ http standard (gets, puts, ecc.).Ricerca di un paradigma da utilizzare per la gestione degli errori generici in Angular da una risposta JSON da Rails

Occasionalmente il mio server Rails produrrà un errore (diciamo errore di convalida allegato all'oggetto) o addirittura nessun errore, nel qual caso vorrei visualizzare qualcosa all'utente - o il errror es. "Il record non ha salvato perché ... "o" Il record è stato aggiornato correttamente ".

Sto tentando di mappare uno schema sul lato Rails e sul lato Angular/client per gestirlo.

Per quanto riguarda Rails:

  • posso certamente passare di nuovo un nodo in ciascuno dei miei file Rabl a contenere le matrici di errore
  • posso anche restituire Rabl diverso controllando nel controller prima di tornare
  • La maggior parte consiglia di utilizzare i codici http (che ha senso) come da here (anche se non sembra esserci un uso coerente dei codici per qualcosa come un errore di convalida).

Per quanto riguarda angolare:

  • suppongo di poter scrivere un response interceptor ma non è sicuro come sarebbe completamente ottenere eliminati.

Immagino che spero di non dover reinventare la ruota qui e qualcuno possa indicarmi un modello che è attualmente utilizzato e suggerito (e localizzato).

risposta

11

Sono andato avanti e implementato ciò che pensavo fosse necessario. Grazie per digger69 per qualche aiuto con questo.

Sul lato Rails, sono andato usando un codice di stato http. Come da here ho concordato con l'utilizzo di un codice di stato http 400 per la convalida degli errori.

Nei miei controllori mi hanno ora qualcosa di simile al seguente:

def create 
    my_obj = MyObj.build_with_params(params) 
    if my_obj.save 
    respond_with(my_obj) # regular RABL response 
    else 
    respond_with_errors(my_obj.errors) 
    end 
end 

Nel mio application_controller.rb ho definito un metodo comune respond_with_errors

# respond back to the client an http 400 status plus the errors array 
def respond_with_errors(errors) 
    render :json => {:errors => errors}, :status => :bad_request 
end 

Nota che il: bad_request simbolo è già definito per Rails secondo here

Sul lato client che mi serviva per intercettare le chiamate HTTP (non solo per la convalida, ma per l'autenticazione . fallimenti troppo (e probabilmente più) Ecco un esempio del mio codice in angolare (grazie al this post per l'aiuto in questo):

var interceptor = ['$rootScope', '$q', function (scope, $q) { 
    function success(response) { 
    return response; 
    } 
    function error(response) { 
    var status = response.status; 

    if (status == 401) { // unauthorized - redirect to login again 
     window.location = "/"; 
    } else if (status == 400) { // validation error display errors 
     alert(JSON.stringify(response.data.errors)); // here really we need to format this but just showing as alert. 
    } else { 
     // otherwise reject other status codes 
     return $q.reject(response); 
    } 
    } 
    return function (promise) { 
    return promise.then(success, error); 
    } 
}]; 
$httpProvider.responseInterceptors.push(interceptor); 

ora posso essere coerente con il mio codice rotaie e affrontare il successo ritorna dalle chiamate http sul client. Sono sicuro di avere ancora qualcosa da fare, ma penso che questo dia una soluzione localizzata.

+0

Mi piace molto questa architettura, ma c'è una cosa che suggerirei di migliorarla. Se si restituisce l'oggetto originale nel payload dei dati, il client lo reimposterà allo stato in cui si trova nel server, quindi se si seleziona una casella e non si riesce a salvare, verrà nuovamente deselezionata quando la richiesta non riuscita ritorna . Angolare lo fa automaticamente. Quindi vorrei suggerire non * solo * inviare gli errori indietro ma l'oggetto originale + un messaggio di errore che viene visualizzato In questo modo il client avrà una versione coerente dei dati del server + il messaggio di errore –

+0

Spiacente, tanto per essere chiari, il i dati rilegati nella pagina verranno automaticamente aggiornati quando utilizzi $ risorse - ovviamente questo potrebbe non essere il caso se stai utilizzando direttamente il servizio $ http –

1

Utilizzare un intercettore di risposta HTTP. Attualmente sto usando con successo in un'applicazione.

http://docs.angularjs.org/api/ng.$http

Dalla documentazione:

$provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) { 
    return function(promise) { 
    return promise.then(function(response) { 
     // do something on success 
    }, function(response) { 
     // do something on error 
     if (canRecover(response)) { 
     return responseOrNewPromise 
     } 
     return $q.reject(response); 
    }); 
    } 
}); 

$httpProvider.responseInterceptors.push('myHttpInterceptor'); 

Nel mio caso ho creato un servizio di feedback, che visualizza sia successo o messaggi di errore a livello globale. Un'altra opzione sarebbe quella di trasmettere le risposte sul rootcope.

+0

Grazie per il commento: avevo appena implementato qualcosa di simile sul lato angolare e ho dovuto implementare del codice in Rails per gestire le risposte RABL. Vedi la mia risposta. –

Problemi correlati