角度:地图来自服务的响应

时间:2018-08-09 08:36:44

标签: angular typescript angular-services

我已经在angular4上工作了一段时间,处理来自服务的JSON响应。但是今天我观察到我的服务使我得到了这样的答复。

info-response.json

{
"1":{
     "id":"1",
     "name":"Anna"
    },
"2":{
     "id":"2",
     "name":"Martin"
    }
}

我用Google进行了搜索,发现它是map,但是如何阅读这种类型的响应,却无法进行迭代。我确实编写了如下服务。

模型是Info.ts

export interface Info{
  id: string;
  name: string;
}

ts文件为:

infoData: Info;
this.groupService.fetchInfo().subscribe(data => {
 this.infoData = data;
 // how to iterate this.infoData
});

服务是:

fetchInfo(): Observable<Info>{
 const url = "/assets/info-response.json"; //as of now I am working on hard coded json as I dont know my map logic is correct of not
 //const url = "/info/getInfo";
 return this.httpClient.get<Info>(url).map(function (data => Info){
   return data;
  });
}

我对map没有任何了解,甚至不确定我的代码是否正确。到目前为止,我还没有尝试过该服务,如上所述,我正在研究硬编码的JSON。请指导我:

我打电话给服务的方式是正确的,处理地图吗? 如何迭代这种类型的响应?

1 个答案:

答案 0 :(得分:1)

是的,您正在致电服务。

关于地图,在您的情况下,最好的考虑方式是RxJS的地图在请求进入时对其进行迭代并将其整体转换。您拨打的每个服务电话都将返回一个响应。如果您打算转换此响应,则可以,使用上述RxJs映射运算符,并对服务器接收的数据对象执行所需的任何转换。这是一个使用RxJs映射运算符将服务器检索的数据对象从哈希值转换为数组的示例:

// Returned data by the api call
// {
// "1":{
//      "id":"1",
//      "name":"Anna"
//     },
// "2":{
//      "id":"2",
//      "name":"Martin"
//     }
// }

fetchInfo(): Observable<Info> {
 const url = "/assets/info-response.json";
 return this.httpClient.get<Info>(url)
  .map((data: Info) => {
    // in here, data is equal to your returned JSON above
    // So, if you wish to turn this into an array
    
    const transformedData = Object.keys(data).map(key => data[key]);
    
    // as you return this output, any operator applied below,
    // as well as the data that will reach your subscribe resolver
    // will look like:
    //
    // [
    //  { "id":"1", "name":"Anna" }
    //  { "id":"2", "name":"Martin" }
    // ]
    
    reuturn transformedData;
  });
}

// As for processing the response now that it is an array...

fetchInfo().subscribe(data => {
  this.infodata = data.map(value => ({ ...value, city: 'Amsterdam' }));
  
  // your infodata object will now look like this:
  //
  // [
  //  { "id":"1", "name":"Anna", "city": "Amsterdam" }
  //  { "id":"2", "name":"Martin", "city": "Amsterdam" }
  // ]
});

另一方面,如果您对服务器返回的响应感到满意,则无需在其上应用map运算符,因为它是多余的。您的服务呼叫将变得简单:

return this.httpClient.get<Info>(url);

一些有用的参考:Object。keys(),Array。map()方法,用于转换结果数组,RxJs的map运算符用于api调用。

这是一个没有演示代码的简单直接的解决方案,其功能与上述代码完全相同:

fetchInfo(): Observable<Info> {
 return this.httpClient.get<Info>("/assets/info-response.json");
}

fetchInfo().subscribe(data => {
  this.infodata = data.keys(key => data[key]).map(value => ({ ...value, city: 'Amsterdam' }));
});

请注意,从RxJ 5开始,不再将map运算符直接应用到可观察对象上,而是通过管道进行应用。

有帮助吗?

编辑:

由于尚未完全支持Object.values,因此我改用Object.keys。

编辑2:

添加了一个简单的解决方案,没有演示代码来解释RxJs的地图