Angular 4,将HTTP响应observable转换为对象observable

16

我刚接触可观察对象的概念,需要一些转换方面的帮助。
我有一个服务,它从Http请求返回一个Observable<Response>,但我需要将其转换为Observable<PriceTag>以在connect方法内部使用该DataSource
有没有什么办法可以做到这一点?

这是我的服务中的方法:

getPriceTags(): Observable<Response> {

    // Set the request headers
    const headers = new Headers({ 'Content-Type': 'application/json' });

    // Returns the request observable
    return this.http.post(Constants.WEBSERVICE_ADDRESS + "/priceTag", null, {headers: headers});

}

这里是DataSource类,我需要将其作为一个Observable<PriceTag>返回:

export class PriceTagDataSource extends DataSource<PriceTag> {

    constructor (private priceTagService: PriceTagService) {
        super();
    }

    connect(): Observable<PriceTag> {

        // Here I retrieve the Observable<Response> from my service
        const respObs = this.priceTagService.getPriceTags();

        // Now I need to return a Observable<PriceTag> 

    }

    disconnect() {}

}

这是来自我的请求响应的一个示例:

{
    // This object is used to check if the query on the server was sucessful
    "query": {
        "sucessful": true
    },

    // These are my PriceTags 
    "tags": [
        {
            "id": "1",
            "name": "MAIN"
        },
        {
            "id": "2",
            "name": "CARD"
        }
    ]
}

一个答案有帮助到您吗? - Robin Dijkhof
3个回答

36

从Angular 4.3开始,这可以自动完成。

示例:

export class SomeService {
    constructor(private http: HttpClient) {}  // <--- NOTE: HttpClient instead of Http

    getSome(): Observable<MyAwesomeObject> {
        return this.http.get<MyAwesomeObject>('myUrl');
    }
}

所以在您的情况下,代码如下:

return this.http.post<PriceTag>(Constants.WEBSERVICE_ADDRESS + "/priceTag", null, {headers: headers});

再次使用HttpClient而不是Http


1
哦,我不知道它可以做到那个...很棒。 - diopside
1
这段代码和以下代码有什么区别吗?`getSome(): Observable<MyAwesomeObject> { return this.http.get('myUrl').map((response) => <MyAwesomeObject>response.json()); }` - Pritesh Acharya
4
对我来说,这实际上没有创建PriceTag对象。 数据仍然是Object类型。 - Grimmy
嗨, 我有一个小问题。有些东西我不明白,在这个解决方案中,我确实可以获取MyAwsomeObject实例的所有属性,但是如果这个类也有一些公共方法,我就无法访问它 - 所以它看起来像是MyAwsomeObject的json表示形式 - 而不是它本身的实例。 我做错了什么吗? - Mariusz
1
好的,我找到了对我的评论的答案。https://dev59.com/o1YN5IYBdhLWcg3wAUD- - Mariusz
但是如果我需要将HTTP响应转换为不同类型怎么办?类似于.NET世界中的AutoMapper? - eddy

5
我猜你的 HTTP 响应是包含价格标签的 JSON?问题在于你想创建一个 PriceTag 对象。你可以将 JSON 转换为 PriceTag 对象,但这样它就不是真正的 PriceTag 对象了。
我们解决这个问题的方法是:
export class Serializable {
  constructor(json?: any) {
    if (json) {
      Object.assign(this, json);
    }
  }
}

然后是一个可序列化的类:

export class PriceTag extends Serializable {}

接着,你的GetPriceTags函数需要进行更改:

getPriceTags(): Observable<PriceTag> {

    // Set the request headers
    const headers = new Headers({ 'Content-Type': 'application/json' });

    // Returns the request observable
    return this.http.post(Constants.WEBSERVICE_ADDRESS + "/priceTag", null, {headers: headers})
    .map(res => new PriceTag(res.json()));

}

1
在Angular 4+中,可以自动完成此操作。您可以更改您的getPriceTags方法:
export class PriceTagService {
    constructor(private http: HttpClient) {}

    getPriceTags<T>(): Observable<T> {

        // Set the request headers
        const headers = new Headers({ 'Content-Type': 'application/json' });

        // Returns the request observable
        return this.http.post<T>(`${Constants.WEBSERVICE_ADDRESS}/priceTag`, null, {headers: headers});

    }
}

您的DataSource类可以是:

export class PriceTagDataSource extends DataSource<PriceTag> {
    constructor (private priceTagService: PriceTagService) {
        super();
    }

    connect(): Observable<PriceTag> {
        // Here you can retrieve the Observable<PriceTag> from service and return directly
        return this.priceTagService.getPriceTags<PriceTag>();
    }

    disconnect() {}
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接