2017-01-27 6 views
2

私はハンドル事業エラー

{ 
    code: 0, // 0 is Ok, all other values is error 
    data: [{...}, {...}, {...}, ...], // data objects 
    message: "" // empty when ok or some error message in other cases 
} 

が、私はこのAPIの通信サービスを作成しようとした形式でレスポンスを返すいくつかのAPIを持っている

import { Injectable } from '@angular/core'; 
import { Http, Response } from '@angular/http'; 
import { Observable } from 'rxjs/Observable'; 

interface IApiResponse<T> { 
    code: number; 
    data: Array<T>; 
    message: string; 
} 

@Injectable() 
export class ApiService { 

    constructor( 
    private http: Http 
) { } 

    apiGet<T>(url: string): Observable<Array<T>> { 
    return this.http.get(url) 
      .map((res: Response) => res.json()) 
      //.map((api: IApiResponse<T>) => api.code === 0 ? api.data : Observable.throw(api.message)) 
      .mergeMap((api: IApiResponse<T>) => api.code === 0 ? api.data : Observable.throw(api.message)) 
      .catch(err => Observable.throw(err)); 
    } 

} 

私は時にコード例外を発生させたいですフィールドは0ではなく、サブスクライブのエラー部分にメッセージを返します。 しかし、Observable.throwをマップに戻すと、エラーではなくサブスクリプションのデータとして返されます。 代わりにmergeMapを試してみると、予想通りに例外がサブスクライブ関数のエラーとして返されますが、データ配列内の各オブジェクトのデータが返されます。それは私にとっては適切ではありません。 これには他の観測可能な関数を使用する必要がありますか?コンポーネントで

サービスの利用

import { Component, OnInit } from '@angular/core'; 

interface ITestItem { 
    id: number; 
    title: string; 
} 

@Component({ 
    selector: 'app-main', 
    templateUrl: './main.component.html', 
    styles: [] 
}) 
export class MainComponent implements OnInit { 

    constructor(
    private apiService: ApiService 
) { } 

    ngOnInit() { 
    this.apiService.apiGet<ITestItem>('/api/test') 
     .subscribe(
     // only data when code = 0 or nothing 
     data => console.log("data section:", data), 
     // handle http errors and message when code != 0 
     error => console.log("error section:", error), 
     () => console.log("api request completed") 
    ); 
    } 

} 

答えて

2

ことが可能である場合mergeMapが観測に結果を変換しますので、これはなぜ起こるか理由はあります。データは配列なのでObservableに変換され、含まれる各要素が放出されます。

RxJS docに基づいて、あなたはかなり近いですアレイ放射として

+0

はい、それは動作します!しかし、私はObservable.throwがマップとマージマップでなぜ動作するのかを理解できません。 – avvensis

+0

map関数は結果をObservableにキャストしないので、マップ関数がObservable.throwを返すとき、それはsubscribeの 'next'関数に送出する値になります。 –

0

をそれを維持する.mergeMapRx.Observable.of()でデータを包みます。あなたはそうのような例外をスローする必要があります:あなたの必要性のためにどんな変更neccessaryを行い、

EDIT詳細

サービスを助け

Observable.throw(new Error(api.message)); 

希望。

getTestData(): any { 
    return this.http.get("testUrlShouldThrowError") 
     .map((api: any) => { 
     if (api.code === 0) { 
      return <IApiResponse<Test>>api.data 
     } 
     else { 
      return Observable.throw(new Error("Error!")) 
     } 
     }); 
    } 

サブスクリプション:

this.testService.getTestData().subscribe(
     data => console.log(data.error.message), 
    ) 
+0

.map(api:IApiResponse )=> api.code === 0 api.data:Observable.throw(new Error(api.message)))は、subscribeのデータ部分にErrorObservableを返します。 – avvensis

+0

@avvensisはい、しかしあなたはあなたのサブスクリプション 'error => console.log(" error section: "、error.error.message)でエラーメッセージにアクセスすることができます' – 12seconds

+0

私はそれに対して何をしますか? – avvensis

関連する問題