2016-04-08 17 views
9

Ho un servizio che interagisce con un server API. Ha il metodo myHttpPost (dati). Questo metodo dovrebbe:In Angular2, come intercettare la risposta di errore da osservabile e trasmetterla al canale di errore

  1. chiamata http.post di angolare al server
  2. se la risposta è stato di 200, di fornire contenuti JSON della risposta al sottoscrittore
  3. se la risposta è stato diverso, processo di risposta e di fornire l'errore elaborati per l'abbonato

la versione corrente del mio metodo è:

postData(path: string, data: Object): Rx.Observable<any> { 
    let json = JSON.stringify(data); 
    return this.http.post(path, json) 
     .map(res => res.json()) 
} 

Questo non sta facendo il punto 3 dall'elenco precedente, perché la mappa è chiamata solo su successo e non su errore. Potrei cambiare la sequenza con l'aggiunta di:

.catch(error => { 
    let myError = prepareErrorContent(error); 
    return Rx.Observable.throw(myError); 
}); 

Poi l'abbonato (un altro servizio) riceve myError (che è ok), ma la documentazione rxjs dice il seguente sulla cattura() metodo: ", continua una sequenza osservabile che è terminato da un'eccezione con la successiva sequenza osservabile. " Ma voglio che la sequenza termini normalmente e non continui. Se utilizzo lo catch() come sopra, la successiva chiamata a postData() dal sottoscrittore non funziona (restituisce immediatamente lo stesso errore invece di effettuare la chiamata http). Penso che sia perché la sequenza non è terminata.

Come fare?

[Edit] Questo è il mio metodo di abbonati che utilizza questo servizio:

this.jsonHttp.postData(path, data) 
    .subscribe(
     struct => onNext(struct), 
     error => { 
      let message = this.jsonHttp.extractError(error); 
      onError(message) 
     }, 
     () => onComplete ? onComplete() : null 
    ); 
+0

Come si chiama il metodo 'postData'? Grazie! –

+0

Si prega di consultare l'aggiornamento nel mio post. – camcam

risposta

16

Infatti, per ogni richiesta HTTP viene creata una catena di elaborazione ed eseguito. Quando la risposta è ricevuta (sia con successo che con errore), la catena è completata.

Se si esegue il doppio della richiesta, non esiste alcun collegamento tra di loro. È possibile avere alcuni collegamenti quando entrambe le richieste fanno parte della stessa catena di elaborazione. Ad esempio quando si utilizzano operatori osservabili come flatMap o switchMap. Ecco un esempio:

return this.http.get(...) 
     .map(res => res.json()) 
     .flatMap(jsonData => { 
      // Can leverage the result of the previous request 
      return this.http.get(...).map(res => res.json()); 
     }); 

Quando si verifica un errore, la catena di elaborazione è rotto e l'operatore è chiamato catch. È possibile restituire un osservabile nel callback associato per continuare la catena di elaborazione. Può essere un osservabile classico o uno errore con Observable.throw. Nel contesto di una richiesta HTTP in Angular2, una risposta con un codice di stato diverso da 2xx viene considerata come un errore.

Quando si restituisce Observable.throw, viene richiamata la seconda richiamata specificata al momento della sottoscrizione. Se è un altro osservabile, viene chiamato il primo callback. Per esempio:

return this.http.get(...) 
     .map(res => res.json()) 
     .catch(res => { 
      // The error callback (second parameter) is called 
      return Observable.throw(res.json()); 
      // The success callback (first parameter) is called 
      // return Observable.of(res.json()); 
     }); 

ho implementato un plunkr che esegue una richiesta (clic su un pulsante), senza intestazione di autenticazione, in modo da un codice di stato 401 è ricevuto. Quando si fa nuovamente clic, viene aggiunta l'intestazione, quindi viene ricevuto un codice di stato 200. Solo per mostrarti che non esiste alcuna relazione tra le due richieste.

Vedere questo plunkr: https://plnkr.co/edit/5WwWpwjvQmJ4AlncKVio?p=preview.

+0

Hai ragione. Ho ripristinato il codice app con la versione precedente e ora funziona. Non so davvero perché non ha funzionato prima, deve essere una piccola differenza, non può nemmeno replicare quell'errore Grazie per il tuo tempo. – camcam

Problemi correlati