在Observable订阅中使用嵌套映射-Angular6

221b

我正在通过API调用(在我的dataservicse.ts文件中)获取一些数据-得到的响应是一种复杂的JSON结构。我可以在相应的Component文件中按如下方式获取响应的特定部分-

这是代表一般结构的JSON对象响应之一-

{
    "address": {
        "building": "1234",
        "coord": [0, 0],
        "street": "123 Main Street",
        "zipcode": "00000"
    },
    "address2": "Test Suite 000",
    "grades": [{
        "grade": "A",
        "score": 3
    }, {
        "grade": "B",
        "score": 4
    }, {
        "grade": "A",
        "score": 2
    }],
    "name": "John Doe",
    "_id": "1212121"
}

现在-我的目标是从每个响应对象中获取'name'属性以及grades属性内的第一个'grade'值-并将它们映射到单独的数组中,以便可以使用* ngFor在表列中显示它们。

这是我的组件代码

export class TestDataComponent implements OnInit {

name$: Object;
grade$: Object;

constructor(private data: DataService, private data2: DataService) { }

ngOnInit() {
   //getAPIData is returning the API response from the dataservices.ts file
   this.data.getAPIData().subscribe(
       data=>console.log(data.response.map(name=>name.name))
       ); //this works fine - I get the names in an array

     this.data2.getAPIData().subscribe(
     data2=>console.log((data2.response.map(grade=>grade.grades)).map(grades 
        => {grades.map((value, index) => value.grade})) //this returns an undefined value
  );
 }

现在-如果我console.log((data2.response.map(grade=>grade.grades))得到一个Array对象数组,例如-

Array - [Array(3), Array(3), Array(2)]

并且它们每个都由“等级”属性“对象数组”组成。(从上方获取第一个数组)-

Array(3)
0:{"grade": "A","score": 3}
1:{"grade": "B", "score": 4}
2:{"grade": "A", "score": 2}

因此-我进一步映射了我的初始反应以实现“等级”值。另外-我只想要一年级-因此我添加了一个简单的条件,如下所示-

console.log((data2.response.map(grade=>grade.grades))
              .map(grades 
                  => {grades.map((value, index) =>{if(index<1) value.grade})}))

如评论中所述-我得到了一个未定义的值。

我不理解这个问题可能很复杂,但是我已经尽力解释得尽可能清楚。我的目标是从每个对象获取第一个“等级”值并将它们显示在数组中-就像名称一样,以便我可以使用它在表上显示它。

我对Angular6还是很陌生,只是从Angular 1.6切换了-所以我很确定自己搞砸了。

通过订阅中的嵌套映射将等级值放入数组的最佳方法是什么?还是有更好的方法来解决?

另外-为了简单起见,请忽略存在第一个订阅的事实(对于name属性)-我在这里展示了它,以便明确我想要实现的目标。

卖主

这是我您要的,因为您从未给出要映射/归约的具体示例。另外,这是原始的JavaScript,但可以轻松转换为RxJS。

// I am assuming that a call to `DataServce.getAPIData()` returns an array
const api_response = [{
    "address": {
        "building": "1234",
        "coord": [0, 0],
        "street": "123 Main Street",
        "zipcode": "00000"
    },
    "address2": "Test Suite 000",
    "grades": [{
        "grade": "A",
        "score": 3
    }, {
        "grade": "B",
        "score": 4
    }, {
        "grade": "A",
        "score": 2
    }],
    "name": "John Doe",
    "_id": "1212121"
}];

// Map and pluck the values you need
const result = api_response.map(v => [v.name, v.grades[0].score])

// Or as an array of objects
const obj_result = result.map(([name, score]) => ({ name, score }))

// Is this what you want?
console.log('Array', result);
console.log('Objects', obj_result);

快速更新

感谢您接受答案。只是想快速介绍一下使用RxJS的外观。我说可能是因为下面的代码片段未经测试。

this.nameAndScores$ = data.getAPIData().pipe(
  map(({ response }) => response),
  map(({ name, grades }) => ( { name, score: grades[0].score } ))
)

假设这nameAndScores$是组件实例的属性,则可以执行*ngFor item in nameAndScores$ | async并避免代码中的任何显式预订。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章