Необработанный отказ (TypeError): недопустимая попытка деструктурировать не повторяемый экземпляр - PullRequest
0 голосов
/ 23 января 2019

Я пытаюсь изучить метод карты.Если я использую этот синтаксис response.data.map(d =>, я могу перебирать массив данных и видеть результаты, но если я использую этот синтаксис response.data.map(([label, CustomStep]) => {, я получаю ошибку ниже:

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

МожетВы говорите мне, как это исправить, чтобы в будущем я сам это исправил?

Ниже приведен фрагмент кода:

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

обновление 1:

эй, я видел в консоли, данные - это массив внутри, что существует так много объектов

 data: Array(19)
        [
            {
                "customFieldValueCode": "player1",
                "customFieldValueName": "player1",
                "isActive": "Y"
            },
            {
                "customFieldValueCode": "player 2",
                "customFieldValueName": "player 2",
                "isActive": "Y"
            }
        ]

Ответы [ 2 ]

0 голосов
/ 23 января 2019

РЕДАКТИРОВАТЬ:

На основе предоставленной структуры данных вы можете изменить свой код на ...

axios
.get('http://world/sports/values')
.then(response => {
    this.setState({
        playerRanks: response.data.map(obj => {
            return obj.customFieldValueName
        })
    })
})

ИЛИ

    ...
    response.data.map(({customFieldValueName}) => {
        return customFieldValueName;
    })
    ...

ИЛИ даже ...

    ...
    response.data.map(({customFieldValueName}) => customFieldValueName)
    ...

Но это было бы мое рекомендуемое решение для обеспечения проверки типов ваших данных и правильной обработки ошибок ...

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

Чтобы предотвратить вашиПри возврате массива выше из набора 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
      })
    }
})

ПРИМЕЧАНИЕ: Я также только что добавил .filter(elem=> elem) в конец моего первого примера, который делает то же самое, что и новая функциональность .reduce(), но делает это в 1N not 2N операций.

Предварительно зарегистрированные данные

Вот как работает метод Array.map() ...

[1,2].map(element=> {
// element === 1, first iteration,
// element === 2, second iteration
})

Вот как Разрушение массива работает ...

[one, two, ...theRest] = [1,2,3,4,5]

// one === 1 and two === 2 and theRest = [3,4,5]

Вот как Разрушение объектов работает ...

{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

Так что в зависимости от того, как вы функционируетеЕсли вы структурированы, вы делаете предположение, что структура данных 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
   ]
]

Я надеюсь, что это поможет концептуально, но если вы хотите работоспособное решение, нам понадобится ...

  1. Структура данных response.data.Можете ли вы предоставить результат console.log( JSON.stringify( response.data, null, 5) )
  2. Конкретные значения, которые вы пытаетесь присвоить новому this.state.playerRanks Array.

PS: Хороший способ увидеть разрушение объекта в действии сВаш текущий код должен измениться ...

.then( response => {

На

.then( ({data}) => {

0 голосов
/ 23 января 2019

В этом случае вы должны быть уверены, что response.data является массивом массивов, потому что для каждой итерации response.data.map функция, которую вы предоставляете map, должна получить массив, чтобы иметь возможность успешно извлекать значения label и CustomStep из-за синтаксиса, с которым вы деструктурируете параметр функции.

Представьте себе 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'

В противном случае, если response.data - это массив объектов, который, по-видимому, связан с тем, что вы успешно можете запустить response.data.map(d => d.customFieldValueName), вы можете обновить свою карту до этого (если вы просто хотите вытянуть customFieldValueName значение вне объекта):

response.data.map(({ customFieldValueName }) => customFieldValueName)
...