У меня есть API, который возвращает ответы в форматеручки в запросе апи
{
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
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")
);
}
}
Да, это работает! Но я не могу понять, почему Observable.throw работает на карте и mergeMap по-разному. – avvensis
Функция карты не передает результаты Observable, поэтому, когда ваша функция карты возвращает Observable.throw, это будет значение, которое оно испускает для функции 'next' для подписки. –