2017-11-13 3 views
1

Angular 4アプリでは、http postでサーバーのログインAPIを呼び出します。サーバは、ログインが成功したか否かにかかわらず、常にスタウト200で応答する。私はサーバーの応答データに基づいてエラーをスローしたい。ログインを呼び出す角度4でhttpステータス200のレスポンスを得るために、.mapに観測可能なエラーを投げる方法

export class AuthenticationService { 
... 
login(username: string, password: string): Observable<any> { 
    let body = `method=login&username=${username}&password=${password}`; 

    return this.http.post('http://localhost/rest.php', body) 
     .map((response: Response) => { 
      let responsedata = response.json(); 
      if (responsedata && responsedata.success == 1) { 
       localStorage.setItem('loggedin',1); 
      } else { 
       // Not logged in successfully 
       Observable.throw(new Error('Not logged in')); 
      } 

     }); 
} 

そして、私のコード()

trytologin() { 
    this.loading = true; 
    this.authenticationService.login(this.model.username, this.model.password) 
     .subscribe(
      data => { 
       // Always returns here regarless of result of login 
       this.router.navigate([this.returnUrl]); 
      }, 
      error => { 
       // ONLY returns here on a NON-server 200 status 
       this.alertService.error(error); 
       this.loading = false; 
      }); 
} 

私は応答を傍受しHttpInterceptorを使用してヘッダを変更することができると思うが、これはやり過ぎのように思えます。 subscribeエラーを200ステータス応答からトリガーする別の方法はありますか?


EDIT

私は成功せずHttpInterceptorを実装してみました。

import {HttpClient, HttpHeaders} from '@angular/common/http'; 
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse,HttpHeaderResponse, HttpErrorResponse} from '@angular/common/http'; 
import {Injectable} from '@angular/core'; 
import {Observable} from 'rxjs/Observable'; 
import 'rxjs/add/observable/of'; 
import 'rxjs/add/operator/map'; 

@Injectable() 
export class LoginInterceptor implements HttpInterceptor { 

constructor() {} 

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { 
    // Need to .map so we can go through each event looking for the HttpResponse 
    // Can't use .do() as it doesn't update per the docs 
    return next.handle(req).map(event => { 
     if (event instanceof HttpResponse) { 

      let e2 = new HttpErrorResponse({status: 405, statusText: 'Auth error'}); 
      // return Observable(e2); // Cannot return as HttpErrorResponse is NOT part of HttpEvent<any> 
      Observable.throw(e2); // <-- Still triggers the success in .subscribe(). Does NOT trigger the .subscribe() error 
      event = event.clone({status: 405, statusText: 'Auth error'}); // <-- change the event status. Can't return HttpErrorResponse as 
     } 

     return event; 
    }); 

} 
} 

.subscribe()成功は常に呼び出されます。


私は間違っていました。 : - 私のコードが失敗した理由/ EDIT#2

掘削のLOTSした後、私が今知っています。しかし、私はまだ解決策がありません!

HttpInterceptorは..... 移動するための方法であるが、 Observer.throw()のみHttpClient.post()が同じドメイン上にある場合にのみ、に動作します! localhostにpost()すると、subscribe()エラーが呼び出されます。私が別のドメインにpost()を呼び出すと、subscribe()エラーが呼び出されません。 Observer.throw()の直後にconsole.log()を貼ります。別のドメインがある場合はログ出力があります。ドメインが同じ場合はログ出力があります。サーバーの出力を制御しており、Access-Control-Allow-Origin: *ヘッダー項目が含まれているため、これがCORSの問題であるかどうかはわかりません。

これはおそらく HttpClientおよび/または HttpInterceptorのバグですか?あるいはrxjsの問題でしょうか?


編集#3

私は単純にintercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>Observable.throw()を返す場合は、私のエラーコードがトリガーされますブロックします。ただし、これはhttp要求でのみトリガされます。私は処理してhttp応答でエラーを投げる必要があります。これを行うには、return next.handle(req).map()を使用して、それぞれHttpResponseイベントを検索する必要があります。

私がしようとするとmap()Observer.throw()を実行すると、それは私のエラーコードを誘発しないとどこにもキャッチされていません。 Observer.throw()以降の行が実行されます。

からは、return Observer.throw()は正しくありません。返品のタイプは正しくありません。

ただし、map()のプレーンJavaScriptをthrow()と呼び出すとエラーコードが表示されます。

普通のthrow()がベストプラクティスなのか、何か他のことをしなければならないかどうかはわかりません。

+0

サーバーからの応答を傍受し、HttpErrorResponse(HTTPではなくHttpClientを使用していると思います)を使用してHTTP応答をエラーにして、そのオブジェクトを返すことができます。このような何かが新しいHttpErrorResponse({status:401、statusText: "Authのエラー"})を返します。 –

答えて

1

あなたは

import { HttpInterceptor, HttpErrorResponse } from '@angular/common/http'; 

import { Observable } from 'rxjs/Observable'; 
import 'rxjs/add/Observable/of'; 
あなたが応答を傍受することができますし、その応答から、あなたが決断を下すことができ

のように働いて、このコードを取得するには、適切なライブラリと観測の方法をインポートする必要があります、

export class YourInterceptor implements HttpInterceptor{ 
    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>{ 
       //check your conditions if fall true send this response as given //below 
       return Observable.throw(new HttpErrorResponse({status:401, statusText:"Error of auth"})); 
     } 
} 

今日試したサンプルコードのスクリーンショットを見つけよう。 Component code where service is being called

+0

HttpErrorResponseはHttpEvent の一部ではないため、Observable.of(new HttpErrorResponse)は使用できません。オリジナルの投稿の編集をご覧ください。 – mminnie

+0

戻り値Observable.throw(新しいHttpErrorResponse({status:401、statusText: "失敗応答"})); –

+0

戻り値Observable.throw(新しいHttpErrorResponse({status:401、statusText: "失敗応答"}));しかし、私はこれが正しい方法であるかどうかは分かりませんが、この変更を投稿すると、エラー固有のコードがトリガーされているのを見ることができます。 –

関連する問題