javascript - Unhandled Rejection (TypeError): Invalid attempt to destructure non-iterable instance - Stack Overflow

I am trying to learn the map method. If I use this syntax response.data.map(d => I am able to iterat

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:

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:

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"
            }
        ]

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:

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:

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"
            }
        ]
Share Improve this question edited Jan 23, 2019 at 18:54 asked Jan 23, 2019 at 15:57 user10803047user10803047 12
  • What is the structure of the data you are expecting to receive? You can only use [] to destructure an array or an iterable; you would use {} to destructure an object. – wlh Commented Jan 23, 2019 at 16:06
  • 1 You should checkout the output of console.log(JSON.stringify( response.data,undefined,2)) The error is similar as const [a,b]=22 – HMR Commented Jan 23, 2019 at 16:07
  • @HMR hey can you tell why your using undefined and 2 in your console and I am able to see the value in the console for this line console.log(JSON.stringify( response.data,undefined,2)) – user10803047 Commented Jan 23, 2019 at 20:57
  • 1 What @HMR and I were doing with this format of console.log() in general making the full (or rather desired) depth of the Object you're logging visible. Using a modern browser console.log(someObj) because it will allow you to inspect the entirety of the Object in the 'dev tools' console, but in a server-side environment console.log() will only give you [Object] and using JSON.stringify(obj), which converts the object to a string, will still only show you the 'fist' level of that Object.... – cantuket Commented Jan 23, 2019 at 21:14
  • 1 @cantuket I use JSON.stringify because even in a browser when you expand a logged object it shows the object as it is now; not as it was at the time of logging (you may have mutated the object to fit or break the code close to the log) For example: const arr = [{name:'Ben'}];console.log(arr);arr[0].name='Jerry'; when you expand the logged object it shows name is Jerry but that wasn't the name at the time of logging. The 2 in JSON.stringify(obj,undefined,2) is the amount of spaces used for the tab size of the formatted JSON. – HMR Commented Jan 25, 2019 at 7:48
 |  Show 7 more ments

2 Answers 2

Reset to default 2

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 remended 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 nulls...

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.

PRE-logged data

Here's how the Array.map() method works...

[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 === [ 
   [ 
     { 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...

  1. Data structure of response.data. Can you provide result of console.log( JSON.stringify( response.data, null, 5) )
  2. Specific values you are trying to assign to the new this.state.playerRanks Array.

PS: A good way to see Object destructuring in action with your current code is to change...

.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.

Imagine data in the following example is the response.data and the parseData function is the function you are passing to the 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.map(({ customFieldValueName }) => customFieldValueName)

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745207854a4616678.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信