Я новичок в 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;
});
}
У вас есть карты как объект, и то, что вам нужно, находится внутри этого объекта. Также выходная часть неверна, у вас нет переменной 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>
cards
, вероятно, не является массивом. Учитывая, что вы пытаетесь извлечь из него пары ключ/значение, вы уже это знаете и неправильно используетеforEach
. Просмотрите, какие методы доступны для объектов . Вы, вероятно, хотите Object.entries().