我正在通过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属性)的事实-我在这里进行了显示,以便明确我想要实现的目标。
答案 0 :(得分:2)
这是我想要的,因为您从未给出要映射/归约的具体示例。此外,这是原始的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
并避免在代码中进行任何明确的预订。
答案 1 :(得分:0)
您正在第二个地图功能中使用带有粗箭头的花括号。使用花括号时,应使用return
关键字返回一个值。