简体   繁体   English

Angular 4正确的方法来投射HTTP响应

[英]Angular 4 proper way to cast http response

I've created a service in Angular 4 and I'm fetching data via REST/JSON (new to Angular) using this code: 我已经在Angular 4中创建了一个服务,并使用以下代码通过REST / JSON(Angular的新功能)获取数据:

Interface 接口

export interface IItem {
    Id: number;
    Title: string;
}

Service 服务

import { IItem } from './item';
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/map';

@Injectable()
export class ItemTest {

    constructor(private _http: HttpClient) {}

    getItems(): Observable<IItem[]> {
        return this._http.get<IItem[]>('url')
            .do(data => {
                console.log(data);
            })
    }
}

The http cast to IITem works fine if the response is in this format 如果响应采用这种格式,则将HTTP强制转换为IITem

[
    {
        "Id": 53,
        "Title": "Test Document 4.docx"
    },
    {
        "Id": 55,
        "Title": "Test Document 2.docx"
    }
]

But the actual response from the server looks like this and the cast doesn't work. 但是来自服务器的实际响应看起来像这样,并且强制转换不起作用。 What's the best way to cast the "results" portion of the response to an array of IItems? 将响应的“结果”部分转换为IItems数组的最佳方法是什么?

{
    "d": {
        "results": [
            {
                "Id": 53,
                "Title": "Test Document 4.docx"
            },
            {
                "Id": 55,
                "Title": "Test Document 2.docx"
            }
        ]
    }
}

Youll want to use the map operator: 您将要使用地图运算符:

@Injectable()
export class ItemTest {

    constructor(private _http: HttpClient) {}

    getItems(): Observable<IItem[]> {
        return this._http.get('url').map((data) => data['d']['results'])              
            .do(data => {
                console.log(data);
            })
    }
}

The specific type for the get should describe the shape of the actual response JSON you expect to receive. get的特定类型应描述您期望接收的实际响应JSON的形状。 Then the compiler can actually help you by telling you whether you're accessing and returning the right things. 然后,编译器实际上可以通过告诉您是否正在访问并返回正确的内容来为您提供帮助 In your case: 在您的情况下:

getItems(): Observable<IItem[]> {
    return this._http.get<{ d: { results: IItem[] } }>('url')
        .map(response => response.d.results)
        .do(data => {
            console.log(data);
        }):
}

Note that none of this is casting the response data, just describing it. 需要注意的是这一切都不是铸造响应数据,只是描述它。


As for your other suggestion: 至于您的其他建议:

.get<IItem[]>(...)
.map((data) => data['d']['results']) 

If you're going to assert the type of the response wrongly then make unsafe property accesses with a result the compiler can only assume is any , you might as well not be using types at all. 如果您将错误地声明响应的类型,然后进行不安全的属性访问,结果编译器只能假定是any ,那么您也可能根本不使用类型。 Don't just ignore the compiler when it tells you you're accessing the wrong properties. 当编译器告诉您正在访问错误的属性时,不要仅仅忽略它。

You'd probably want to run a few mapping utilities 您可能需要运行一些映射实用程序

http.get(url)
.map(response => response.json())
.map(response => response.d.results)
.map(results => results.map(item => return Object.create(IItem, item))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM