我知道这是一个普遍的问题,但是我已经用尽了google,并尝试了许多方法。任何反馈都值得赞赏。
HTTPClient是Angular 5+,因此它返回根据响应JSON数据创建的对象。我从无法控制的终结点那里收到了大量的JSON响应,我想在应用中使用大约20%的响应,而忽略其余的响应。
我真的在努力避免使用一系列模板或导出对象或其他任何东西,并试图将这个庞大的未类型化Observable转换为具有数百个字段(其中很多是数组)的类型化对象。该应用程序所需的只是一个非常小的对象组成的数组,每个对象具有3个字段。这3个字段都位于JSON响应中,我想将它们映射到我的对象。仅当您使用完整的响应对象时,map才起作用,除了在如果您要将几个字段映射到1个对象,而我试图映射到我的小对象的数组。
已更新
基本上,我希望该服务将类型为DislayData的对象返回到预订该模块的模块,但是我只得到一个对象。这不是我最终要做的,但是如果可以证明我可以将响应的主体映射到所需的返回类型,则可以开始分解响应主体,并根据我的需要返回我真正需要的类型的数组。愚蠢的DisplayData对象。再次感谢!
export interface DislayData {
body: any;
}
...
export class DataService {
constructor(private http: HttpClient) { }
/** GET data from the black box */
getData(): Observable<DislayData> {
return this.http.get<HttpResponse<any>>(searchUrl, { observe: 'response' })
.pipe(
map(res => {
return res.body as DislayData;
}
tap(res => console.log(//do stuff with entire respoonse also)),
catchError(err => this.handleError(err)));
}
private handleError(error: HttpErrorResponse) {
...
答案 0 :(得分:0)
您知道应答对象的结构吗?
如果是,则可以执行以下操作:
item$ = new BehaviorSubject<any>({});
item = {
foo: 'a',
bar: 'b',
iton: [1, 2, 3],
boo: {
far: 'c'
}
};
logNewItem() {
this.item$
.pipe(
map(response => {
if (response.foo
&& response.iton
&& response.iton.length >= 3
&& response.boo
&& response.boo.far) {
let newItem = {
foo: response.foo,
iton2: response.iton[2],
far: response.boo.far
};
console.log(newItem); // output: Object { foo: "a", iton2: 3, far: "c" }
}
})
)
.subscribe();
this.item$.next(this.item);
}
基本上,您可以简单地确保属性存在,直接调用它们并将它们映射到更合适的对象。
我强烈建议为要接收的对象创建一个接口,并为要映射到的对象创建一个接口或类。在这种情况下,您还可以像这样编写更紧凑的代码:
[...]
map(response: MyAPIResponse => {
let newItem = new NewItem(response);
console.log(newItem); // output: Object { foo: "a", iton2: 3, far: "c" }
}
})
[...]
class NewItem {
foo: string;
iton2: string;
far: string;
constructor(apiResponse: MyAPIResponse) {
//Validate parameter first
this.foo = apiResponse.foo;
this.iton2 = apiResponse.iton[2];
this.far = apiResponse.boo.far;
并使您的代码更具可读性。