[英]Unhandled Rejection (TypeError): Invalid attempt to destructure non-iterable instance
I am trying to learn the map method. 我正在尝试学习地图方法。 If I use this syntax
response.data.map(d =>
I am able to iterate data array and see the results, but if I use this syntax response.data.map(([label, CustomStep]) => {
, I am getting the error below: 如果我使用此语法
response.data.map(d =>
可以迭代数据数组并查看结果,但是如果我使用此语法response.data.map(([label, CustomStep]) => {
,正在收到以下错误:
Unhandled Rejection (TypeError): Invalid attempt to destructure non-iterable instance
Can you tell me how to fix it, so that in future I will fix it myself? 您能告诉我如何修复它,以便将来自己修复吗?
Providing my code snippet below: 在下面提供我的代码段:
axios
.get('http://world/sports/values')
.then(response => {
console.log("sports--->", response.data.map(d => d.customFieldValueName));
//this.setState({ playerRanks: response.data.map(d => d.customFieldValueName) });
// es6 map
//Unhandled Rejection (TypeError): Invalid attempt to destructure non-iterable instance
this.setState({
playerRanks: response.data.map(([label, CustomStep]) => {
label.customFieldValueName
})
})
})
update 1: 更新1:
hey, I saw in console, data is an array inside that there are so many objects 嘿,我在控制台中看到,数据是一个数组,里面有很多对象
data: Array(19)
[
{
"customFieldValueCode": "player1",
"customFieldValueName": "player1",
"isActive": "Y"
},
{
"customFieldValueCode": "player 2",
"customFieldValueName": "player 2",
"isActive": "Y"
}
]
EDIT: 编辑:
Based off the data structure provided you could modify your code to... 根据提供的数据结构,您可以修改代码以...
axios
.get('http://world/sports/values')
.then(response => {
this.setState({
playerRanks: response.data.map(obj => {
return obj.customFieldValueName
})
})
})
OR 要么
...
response.data.map(({customFieldValueName}) => {
return customFieldValueName;
})
...
OR even... 甚至...
...
response.data.map(({customFieldValueName}) => customFieldValueName)
...
But this would be my recommended solution to provide type checking on you data and proper error handling... 但这是我推荐的解决方案,可以对您的数据进行类型检查并进行适当的错误处理...
axios
.get('http://world/sports/values')
.catch(err=> console.log(err))
.then(({data}) => { // Axios always returns an Object, so I can safely 'attempt' to destructure 'data' property
if (data && data.length) { // making sure 'data' does exist, it is an Array and has > 0 elements
this.setState({
playerRanks: data.map(obj => { // Not destructuring here in case obj isn't actually an Object
if (obj && obj.customFieldValueName) return customFieldValueName;
return null;
}).filter(elem=> elem) // BIG-O notation: This sequence is O(2N), as in iterates over the entire Array first with .map(), then iterates over the entire Array again with .filter() to clear out 'null' values
})
}
})
In order to prevent your returned Array above from having a bunch of null
elements when they don't conform to our assertions, you can use an Array.reduce()
method to 'filter' out any null
s... 为了防止上面返回的Array在不符合我们的断言的情况下包含一堆
null
元素,可以使用Array.reduce()
方法来“过滤”任何null
s。
axios
.get('http://world/sports/values')
.catch(err=> console.log(err))
.then(({data}) => { // Axios always returns an Object, so I can safely 'attempt' to destructure 'data' property
if (data && data.length) { // making sure 'data' does exist, it is an Array and has > 0 elements
this.setState({
playerRanks: data.reduce((acc,obj) => { // Not destructuring here in case obj isn't actually an Object
if (!obj || !obj.customFieldValueName) return acc; // If it doesn't meet assertions just return the existing accumulator (don't add another element .ie 'null')
return [
...acc, // If it conforms to the assertions the return a new accumulator, by first spreading in all existing elements and the adding the new one (customFieldValueName)
customFieldValueName
]
},[]) // BIG-O notation: This is O(1N) or O(N), as in it will only iterate over the Array one time and the reduce() function will filter out 'null' values at the same time
})
}
})
NOTE: I also just added .filter(elem=> elem)
to the end of my first example, which does the same thing as the new .reduce()
functionality, but does this in 1N
not 2N
operations. 注意: 我也只是在第一个示例的末尾添加了
.filter(elem=> elem)
,它与新的.reduce()
功能具有相同的功能,但是在1N
而不是2N
操作中完成。
PRE-logged data 预先记录的数据
Here's how the Array.map()
method works... 这是
Array.map()
方法的工作方式...
[1,2].map(element=> {
// element === 1, first iteration,
// element === 2, second iteration
})
Here's how Array destructuring works... 这是数组解构的工作方式...
[one, two, ...theRest] = [1,2,3,4,5]
// one === 1 and two === 2 and theRest = [3,4,5]
Here's how Object destructuring works... 对象解构的工作原理如下...
{one, three, ...theRest} = {one: 1, two: 2, three: 3, four: 4, five: 5}
// one === 1 and three === 3 and theRest === {two: 2, four: 4, five: 5}
// notice order doesn't matter here (three vs two), but you need to access valid properties from the object you're deetructuring from
So based on the way you function is structured you are making the assumption that the data structure of response.data
is... 因此,根据功能的结构方式,您假设
response.data
的数据结构为...
response.data === [
[
{ customFieldValueName: 'any value' }, // label
{} // CustomStep (this could be any value, not necessarily an Object)
],
[
{ customFieldValueName: 'any value' }, // label
'any value' // CustomStep
]
]
I hope this helps conceptually, but if you'd like a workable solution we will need... 我希望这在概念上有所帮助,但是如果您想要一个可行的解决方案,我们将需要...
response.data
. response.data
数据结构。 Can you provide result of console.log( JSON.stringify( response.data, null, 5) )
console.log( JSON.stringify( response.data, null, 5) )
this.state.playerRanks
Array. this.state.playerRanks
数组的特定值。 PS: A good way to see Object destructuring in action with your current code is to change... PS:查看使用当前代码进行对象分解的一种好方法是更改...
.then( response => {
To 至
.then( ({data}) => {
In this case, you should be certain that response.data
is an array of arrays, because for each iteration of response.data.map
, the function you are providing to the map
must receive an array to be able to successfully pull the label
and CustomStep
values, due to the syntax with which you are destructuring the function parameter. 在这种情况下,您应该确定
response.data
是一个数组数组,因为对于response.data.map
每次迭代,您提供给map
的函数必须接收一个数组才能成功提取label
并CustomStep
值, CustomStep
要用来解构function参数的语法。
Imagine data
in the following example is the response.data
and the parseData
function is the function you are passing to the map
: 假设以下示例中的
data
是response.data
,而parseData
函数是您要传递给map
的函数:
let data = [
[{ customFieldValueName: 'field name' }, { stepData: {} }],
[{ customFieldValueName: 'another field name' }, { stepData: {} }]
];
let parseData = ([label, CustomStep]) => console.log(label.customFieldValueName);
parseData(data[0]); // prints out 'field name'
Otherwise, if response.data
is an array of objects, which it seems like it is due to you successfully being able to run response.data.map(d => d.customFieldValueName)
, you could update your map to this (if you simply want to pull the customFieldValueName
value out of the object): 否则,如果
response.data
是一个对象数组,这似乎是由于您能够成功运行response.data.map(d => d.customFieldValueName)
,则可以将地图更新为此(如果您只是想将customFieldValueName
值从对象中拉出):
response.data.map(({ customFieldValueName }) => customFieldValueName)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.