Пытаюсь использовать выборку через js. Он возвращается, как будто на самом деле не вызывает никаких данных. Где я ошибаюсь?

У меня возникли проблемы с поиском каких-либо ресурсов для этого. Все, что мне нужно, это помощь в правильном направлении, чтобы получить что-то осязаемое для использования в HTML. Поэтому в основном, когда я вызываю console.log(keys), я не получаю объекты json в своей консоли, как я привык. Project специально просит сделать это через выборку.

function getFromSWAPI() {

    fetch("https://swapi.dev/api/people/1")
    .then(function (response) {
        return response.json()
    })
    .then(function(data){
        updateInfo(data)
    })
    .catch(function(err) {
        console.warn(err)
    })
}

const updateInfo = responseJSON => {
    console.log(responseJSON.data)
    let keys = Object.keys(responseJSON.data)
    console.log(keys)
}

Вы вызываете updateInfo с объектом данных, поэтому responseJSON ЯВЛЯЕТСЯ данными. Итак, уберите .data после responseJSON.

Lennholm 10.04.2022 06:32
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Сравнение структур данных: Массивы и объекты в Javascript
Сравнение структур данных: Массивы и объекты в Javascript
Итак, вы изучили основы JavaScript и хотите перейти к изучению структур данных. Мотивация для изучения/понимания Структур данных может быть разной,...
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели
Прошлая статья была первой из цикла статей о создании системы электронной коммерции с использованием Keystone.js, и она была посвящена главным образом...
Приложение для отслеживания бюджета на React js для начинающих
Приложение для отслеживания бюджета на React js для начинающих
Обучение на практике - это проверенная тема для достижения успеха в любой области. Если вы знаете контекст фразы "Практика делает человека...
Стоит ли использовать React в 2022 году?
Стоит ли использовать React в 2022 году?
В 2022 году мы все слышим о трендах фронтенда (React, Vue), но мы не знаем, почему мы должны использовать эти фреймворки, когда их использовать, а...
0
1
37
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Первый: почему не работает console.log / почему вы получаете ошибку TS «Невозможно преобразовать неопределенное или нулевое значение в объект в Function.keys»?

Потому что responseJSON не имеет свойства с именем «данные», потому что ответ API не включает свойство с именем «данные». Я подозреваю, что это имя появляется здесь, потому что вы не понимаете, что такое HTTP-ответы и как работают промисы. Итак, давайте начнем с самого начала.

fetch возвращает объект HTTP-ответ, внутри которого содержится некоторый текст. Вы получаете доступ к этому тексту, выполняя:

let text = await response.text()

Или, если вы используете связанные обработчики .then (как в вашем образце), вы делаете следующее:

.then((response) => {
    return response.text()
})

Если вы знаете, что текст является допустимым JSON (а вы это делаете), то вы можете извлечь текст и и разобрать его в значение с помощью одной операции: response.json() (что вы и делаете).

Это возвращает обещание, содержащее значение, закодированное JSON. Если значение является объектом, оно будет иметь свойства, описанные этим JSON.

Какими свойствами будет обладать ваш объект? Откройте этот URL-адрес в своем браузере, и вы увидите их: «год_рождения», «создано», «отредактировано», «цвет_глаз», «фильмы», «пол», «цвет_волос», «рост», «родной мир», "масса", "имя", "цвет кожи", "виды", "звездолеты", "url", "транспортные средства".

«данные» не входят в этот список.

Вот что вы делаете с информацией из ответа:

.then(function (response) {
    return response.json()
})
.then(function(data){
    updateInfo(data)
})

Таким образом, вы передаете анализируемое значение непосредственно в функцию updateInfo.

Затем функция updateInfo пытается зарегистрировать свойство .data полученного значения (которого не существует). То есть .data есть undefined.

Регистрация неопределенного объекта не является ошибкой. Но Object.keys выкинет, если будет undefined:

Object.keys(undefined)
//> Uncaught TypeError: can't convert undefined to object

Исправление заключается в удалении .data как из оператора журнала, так и из вызова Object.keys.

Второй:, это должен был быть ваш первый шаг отладки. Даже не понимая всего вышесказанного: если операции с точками данных, скрытыми внутри значения, не выполняются, наиболее очевидным первым шагом отладки является «сделать шаг назад» и попытаться изучить переменную, с которой вы работаете.

Чтобы проиллюстрировать: если console.log(myThing.items[0].parent.nodeName) терпит неудачу, вы должны немедленно попробовать console.log(myThing) — это позволяет вам проверить переменную myThing, чтобы вы могли вручную проверить, является ли путь, к которому вы обращаетесь, законным. Одна из самых распространенных ошибок, которую совершают разработчики с любым уровнем опыта, заключается в том, что они указывают неверный путь к данным просто потому, что человеку свойственно ошибаться. (Typescript поможет вам заметить это во время написания кода, но вы должны научиться отслеживать проблемы без помощи инструмента, иначе вам всегда будет нужен этот инструмент.)

В третьих: Как я уже упоминал в первом черновике этого поста, вам не хватает некоторых утверждений return.

Самое главное, что ваша getFromSWAPI функция ничего return не делает. Вы должны returnfetch, если хотите, чтобы вызывающие абоненты получали данные.

function getFromSWAPI() {
    return fetch("https://swapi.dev/api/people/1")
    // ...rest of chained thens

Кроме того, вам нужно вернуть что-нибудь внутри обработчика .then, где вы вызываете updateInfo. То, что вы возвращаете, зависит от цели updateInfo:

  • если предполагается, что updateInfo изменяет необработанные данные API в интересах нижестоящего кода, вы должны вернуть результат его вызова:

    .then(function(data){
        return updateInfo(data)
    })
    
  • если предполагается, что updateInfo вызывает какой-то побочный эффект (например, обновление локального кеша необработанными данными или запуск события и т. д.), то вы можете «обойти» функцию: вызвать ее, но перенаправить исходное значение в нисходящий код:

    .then(function(data){
        updateInfo(data) // could do _anything_ with data
        return data // passes the original data onward
    })
    

Незапрошенный обзор кода

  • Вы определяете одну функцию, используя ключевое слово function, а другую определяете как константную стрелочную функцию:

    function getFromSWAPI() { /* stuff */ }
    const updateInfo = responseJSON => { /* stuff */ }
    

    Оба шаблона работают нормально, но вы должны стараться быть последовательными. Мой совет: если вы все еще изучаете JS, отдайте предпочтение ключевому слову function, потому что оно более явное.

  • Предпочитайте использовать async/await вместо цепочек обработчиков.

    Вы можете определить функции как async, а затем awaitТолько конкретные операции, которые являются асинхронными. В вашем случае updateInfo, похоже, не выполняет никакой асинхронной работы, поэтому отстойно, что он должен жить внутри этого обещания, состоящего из трех частей. Я бы пошел с этим:

    async function getFromSWAPI() {
        let response = await fetch("https://swapi.dev/api/people/1")
        let data = await response.json()
        updateInfo(data)
        return data
    }
    

starwars.js:24 TypeError: невозможно преобразовать undefined или null в объект в Function.keys (<анонимно>) в updateInfo (starwars.js:32:23) в starwars.js:21:16 (анонимно) @ starwars.js: 24 Promise.catch (асинхронный) getFromSWAPI @ starwars.js:23 это то, что я запускаю вот так

Cody Whitt 10.04.2022 06:35

В данном случае это не проблема. Вопрос спрашивает, почему вызовы console.log в обратных вызовах не регистрируют данные, которые ожидает спрашивающий.

Lennholm 10.04.2022 06:36
Ответ принят как подходящий

Итак, в вашем коде есть небольшая ошибка,

В этой строке

{...}
.then(function (response) {
        return response.json()
    })
{...}

вы уже вернули json и, таким образом, получаете к нему доступ в следующей строке

{...}
.then(function (data) {
        updateInfo(data)
    })
{...}

Поскольку возвращенные данные сами по себе являются реальными данными, вам не нужно повторно обращаться к ним с помощью свойства данных здесь

{...}
const updateInfo = responseJSON => {
    console.log(responseJSON.data)
    let keys = Object.keys(responseJSON.data)
    console.log(keys)
}

Готовый код будет выглядеть так -

 function getFromSWAPI() {

    fetch("https://swapi.dev/api/people/1")
    .then(function (response) {
        return response.json()
    })
    .then(function(data){
        updateInfo(data)
    })
    .catch(function(err) {
        console.warn(err)
    })
}

const updateInfo = responseJSON => {
    console.log(responseJSON)
    let keys = Object.keys(responseJSON)
    console.log(keys)
}

Alternatively, I would suggest you use async/await if you are using fetch inside a function.

Другие вопросы по теме