Angular:来自服务的地图响应

Angular: map response from service

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

信息-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,如上所述。请指导我:

我调用服务的方式对吗,处理地图? 如何迭代这种类型的响应?

是的,您调用的服务是正确的。

关于 map,在你的情况下最好的思考方式是 RxJS 的 map 在请求传入时迭代它们并将它们作为一个整体进行转换。您拨打的每一个服务电话都会 return 一个响应。如果您的意图是转换此响应,那么是的,使用上面的 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" }
  // ]
});

另一方面,如果您对服务器 return 编辑的响应感到满意,则无需对其应用地图运算符,因为它是多余的。您的服务电话将变得简单:

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

一些有用的参考资料:Object.keys(), Array.map() method used to transform your result array, RxJs's map operator used on your api calls.

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

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' }));
});

请注意,从 RxJs 5 开始,map 运算符不再直接应用于可观察对象,而是通过管道。

这有帮助吗?

编辑:

由于Object.values还没有完全支持,我用Object.keys代替。

编辑 2:

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