Итерация объекта из внешнего API

Я новичок в Javascript и хотел создать приложение, которое показывает результаты из внешнего API. Я попробовал код ниже, и я всегда получаю сообщение об ошибке в консоли, говорящее, что forEach не является функцией. Я понимаю, что получаю данные в объекте. Я пробовал использовать map() и for iteraton, но ничего. Любая помощь будет оценена.

document.addEventListener("DOMContentLoaded", Mtg);

function Mtg() {
  fetch("https://api.magicthegathering.io/v1/cards")
    .then((res) => res.json())
    .then((cards) => {
     
      let output = "";
      
      cards.forEach((key,value) => {
       
        output += `
          <div>${card.name}</div>
          <div>${card.imageUrl}</div>
        `
      });

      console.info(cards);

      document.getElementById("mtgCardsContainer").innerHTML = output;
    });
}




cards, вероятно, не является массивом. Учитывая, что вы пытаетесь извлечь из него пары ключ/значение, вы уже это знаете и неправильно используете forEach. Просмотрите, какие методы доступны для объектов . Вы, вероятно, хотите Object.entries().
Ouroborus 18.12.2020 10:55
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
1
73
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

У вас есть карты как объект, и то, что вам нужно, находится внутри этого объекта. Также выходная часть неверна, у вас нет переменной card. Так,

function Mtg() {
  fetch("https://api.magicthegathering.io/v1/cards")
    .then((res) => res.json())
    .then(({cards}) => { // destruct cards from object
     
      let output = "";
      
      cards.forEach((card) => {
       
        output += `
          <div>${card.name}</div>
          <div>${card.imageUrl}</div>
        `
      });

      document.getElementById("mtgCardsContainer").innerHTML = output;
    });
}

Ваша логика верна, вы просто немного ошиблись с нацеливанием на правильную часть ответа.....

Когда вы делаете запрос на выборку, вы возвращаете объект JSON. Вы решили назвать эти карты объектов.

В этом случае объект JSON возвращает объект, который вы назвали «карты», который сам содержит массив, также называемый картами, поэтому для доступа к этому массиву вам необходимо настроить следующее:

cards.cards.forEach((item, index) => {
 console.info(item)
});

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

.then((data) => {
     
  let output = "";
      
  data.cards.forEach((item, index) => {
   console.info(item)
    output += `
      <div>${item.name}</div>
      <div>${item.imageUrl}</div>
    `
  });
  ...
});

Сделал рефакторинг и добавил комментарии. Удачи:

/**
 *
 * @param card {Object}
 * @returns {string} as HTML
 */
const cardTemplateHTML = (card) => {

  return `
    <div>${card.name}</div>
    <div>${card.imageUrl}</div>
  `
};

/**
 *
 * @param cards {Object}
 */
const renderCards = ({cards}) => { /*
      note: your currently inject the object data that contains cards. So by using the modern syntax { cards }
      you don't have to write 'const {cards} = data' or 'const cards = data.cards'
      */
  const mtgCardsContainer = document.getElementById("mtgCardsContainer");

  //generate HTML
  const cardsHTML = cards.map(card => {
    //generete the HTML for every entry
    return cardTemplateHTML(card)
  })
      //merge the list together into one string
      .join('');

  //update DOM
  mtgCardsContainer.innerHTML = cardsHTML;
}

const Mtg = () => {
  // make fetch promise
  fetch("https://api.magicthegathering.io/v1/cards")
      //fetch result, returns new promise
      .then((res) => res.json())
      //fetch result, returns the rendered json data
      .then((data) => renderCards(data)); /* return data example: data = { cards } */
}

//Load
document.addEventListener("DOMContentLoaded", Mtg);
<div id = "mtgCardsContainer">

</div>

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