Angular - HttpClient:将方法对象结果映射到数组属性

时间:2017-10-12 01:37:39

标签: arrays json angular rxjs angular-httpclient

我正在调用一个返回JSON对象的API。我只需要数组的值来映射到Observable。如果我调用api只返回数组我的服务调用工作。

以下是我的示例代码..

// my service call ..
import { Injectable } from '@angular/core';
import {Observable} from 'rxjs/Observable';
import {Show} from '../models/show';
import {HttpClient} from '@angular/common/http';

@Injectable()
export class MyService {

  constructor(private http: HttpClient ) { }


  findAllShows(): Observable<Show[]> {
    return this.http
      .get<Show[]>(`${someURL}/shows`)
  }
}

如果返回的是JSON对象,如下面的那个失败..

// Service API that FAILS ...
{
  "shows": [
    {
      "id": "123f9165-80a2-41d8-997a-aecc0bfb2e22",
      "modified": "2017-08-13 15:54:47",
      "name": "Main Show1"
    },
    {
      "id": "456f9165-80a2-41d8-997a-aecc0bfb2e22",
      "modified": "2017-08-14 15:54:47",
      "name": "Main Show2"
    },
    {
      "id": "789f9165-80a2-41d8-997a-aecc0bfb2e22",
      "modified": "2017-08-17 15:54:47",
      "name": "Main Show3"
    }
  ]
}

现在,只要我返回数组

,这个就可以了
// Service API that Works ...
[
    {
      "id": "123f9165-80a2-41d8-997a-aecc0bfb2e22",
      "modified": "2017-08-13 15:54:47",
      "name": "Main Show1"
    },
    {
      "id": "456f9165-80a2-41d8-997a-aecc0bfb2e22",
      "modified": "2017-08-14 15:54:47",
      "name": "Main Show2"
    },
    {
     "id": "789f9165-80a2-41d8-997a-aecc0bfb2e22",
      "modified": "2017-08-17 15:54:47",
      "name": "Main Show3"
    }
  ]

如何将JSON对象Observable映射到Array Observable ???

5 个答案:

答案 0 :(得分:11)

您只需.map()您的http调用Observable即可返回您想要的数据类型。

findAllShows(): Observable<Show[]> {
    return this.http
        .get(`${someURL}/shows`)
        .map(result=>result.shows)
}

您的httpClient.get()应该返回Observable,您明确表示它Observable<Show[]>。您.map()是一个将observable转换为新值的运算符。

有关.map()运营商的更多信息:http://reactivex.io/documentation/operators/map.html

答案 1 :(得分:6)

应代替HttpClient使用的最新http没有map方法。您应该先通过import { map } from 'rxjs/operators';进行导入 然后您应该以这种方式使用它:

this.http.get(`${someURL}/shows`).pipe(
        map(res => res['shows'])
    )

答案 2 :(得分:3)

.map(res=> res['shows'] )可以解决问题

答案 3 :(得分:2)

全部谢谢, 通过提供服务器发回的传输对象接口,我能够通过组合来自@ Arun Redhu的响应来找到解决方案。然后由@CozyAzure提供解决方案,使用.map()将一个Observable转换为正确的Observable Show []。

下面的完整解决方案,感兴趣的人。

import {Observable} from 'rxjs/Observable';
import {Contact} from '../models/show';
import {environment} from '../../../environments/environment';
// Use the new improved HttpClient over the Http
// import {Http, Response} from '@angular/http'; 
import {HttpClient} from '@angular/common/http';

// Create a new transfer object to get data from server
interface ServerData {
  shows: Show[];
}

@Injectable()
export class ShowsService {

  constructor(private http: HttpClient ) { }

// want Observable of Show[]
  findAllShows(): Observable<Show[]> {  
    // Request as transfer object <ServerData>
    return this.http
      .get<ServerData>(`${apiURL}/shows`)
     // Map to the proper Observable I need 
      .map(res => <Show[]>res.shows); 

  }
}

现在一切都好!!!谢谢 。因此,根据返回的数据,我可以直接使用或映射到我需要的正确Observable。

答案 4 :(得分:0)

有两种方法可以做到这一点。您可以使用import javax.inject.{Inject, Singleton} import play.api.http.DefaultHttpFilters import play.api.http.EnabledFilters import play.api.mvc.{EssentialAction, EssentialFilter} import scala.concurrent.ExecutionContext // Our example filter @Singleton class ExampleFilter @Inject()(implicit ec: ExecutionContext) extends EssentialFilter { override def apply(next: EssentialAction) = EssentialAction { request => next(request).map { result => result.withHeaders("X-ExampleFilter" -> "foo") } } } // All our filters class Filters @Inject()( defaultFilters: EnabledFilters, // respect play.filters.enabled and play.filters.disabled exampleFilter: ExampleFilter, // you can pass user-defined filter ) extends DefaultHttpFilters(defaultFilters.filters: _*) 运算符从observable中将一种类型的observable映射到另一种类型,而第二种方法包括在界面的帮助下。

第一种方法(在.map的帮助下)

.map

并在第二种方法中借助于包装接口

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

import { Observable } from 'rxjs/Observable';

import 'rxjs/add/operator/map';

interface ItemsResponseObj {
    id: string,
    modified: string,
    name: string
}

interface ItemsResponse {
    shows: Array<ItemsResponseObj>;
}

@Injectable()
export class AppService {

    constructor(private http: HttpClient) { }

    getData(): Observable<ItemsResponseObj[]> {
        return this.http.get<ItemsResponse>('api/api-data.json')
            .map(res => res.shows);
    }

}