Делаю проект на javascript с API от restCountries https://restcountries.com/#rest-countries-v3-vs-v31 Я хочу создать цикл forEach, в котором я могу просмотреть результат и создать что в функции showCountry(). Но я не знаю, что я должен поставить перед циклом forEach? Что может быть актуально? Заранее спасибо!
const countries = document.querySelector('.countries')
const lang = document.getElementById('search').value
const btn = document.getElementById('btn')
function getCountries(){
const search = document.querySelector('.search').value
fetch(`https://restcountries.com/v3.1/lang/${search}`,{
method: "GET",
})
.then((response) => response.json())
.then((data) => console.info(data));
??.forEach(api=> {
showCountry(api)
})
}
function showCountry(data){
const country = document.createElement('div')
country.classList.add('country')
country.innerHTML =
`<div class = "country-img">
<img src = "${data.flag}" alt = "">
</div>
<div class = "country-details">
<h5 class = "countryName">${data.name}</h5>
<p><strong>Population:</strong>${data.population}</p>
<p><strong>SubRegion:</strong>${data.subregion}</p>
<p><strong>Capital:</strong>${data.capital}</p>
<p class = "languageName"><strong>Language:</strong>${data.lang}</p>
</div>`
countries.appendChild(country)
}
HTML;
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<meta http-equiv = "X-UA-Compatible" content = "IE=edge">
<meta name = "viewport" content = "width=device-width, initial-scale=1.0">
<link href = "https://unpkg.com/[email protected]/css/boxicons.min.css" rel = "stylesheet">
<link rel = "stylesheet" href = "style.css">
<title>Countries</title>
</head>
<body>
<div class = "container">
<h1>Search country by language!</h1>
</div>
<div class = "container">
<div class = "controls">
<i class = "bx bx-search"></i>
<input type = "text" placeholder = "search by language.." id = "search" class = "search">
</div>
<button id = "btn" onclick = "getCountries()">Search Country</button>
</div>
<div class = "countries">
</div>
<script src = "script.js"></script>
</body>
</html>
Решение (с новыми ключевыми словами async/await)
async function getCountries(){
const search = document.querySelector('.search').value;
const response = await fetch(`https://restcountries.com/v3.1/lang/${search}`,{
method: "GET",
});
const data = await response.json();
data.forEach(api=> {
showCountry(api)
})
}
Решение (с then
)
function getCountries(){
const search = document.querySelector('.search').value
fetch(`https://restcountries.com/v3.1/lang/${search}`,{
method: "GET",
})
.then((response) => response.json())
.then((data) =>
data.forEach(api=> {
showCountry(api)
})
);
}
Ответ на проблему [object][object], упомянутую в комментарии -
Ваш ответ API data
имеет свойства, отличные от того, что вы используете в своем коде.
Обновленный метод -
function showCountry(data){
const country = document.createElement('div')
country.classList.add('country')
country.innerHTML =
`<div class = "country-img">
<img src = "${data?.flags?.png}" alt = "">
</div>
<div class = "country-details">
<h5 class = "countryName">${data?.name?.common}</h5>
<p><strong>Population:</strong>${data?.population}</p>
<p><strong>SubRegion:</strong>${data?.subregion}</p>
<p><strong>Capital:</strong>${data?.capital}</p>
<p class = "languageName"><strong>Language:</strong>${data?.languages?.eng}</p>
</div>`
countries.appendChild(country)
}
Пропустил, обновил ответ. Спасибо!
Спасибо! выборка и поиск работают супер! Но теперь я получаю NO FOUND 404 и объект объекта, где должны быть флаг и имя. Это все, что вы можете увидеть, что может быть не так? Заранее спасибо!
Обновил ответ, попробуйте.
fetch(`https://restcountries.com/v3.1/lang/${search}`,{
method: "GET",
})
.then((response) => response.json())
.then(data => {
data.forEach(api => {
showCountry(api)
}
});
См. «Как ответить » и Объяснение полностью основанных на коде ответов». Хотя это может быть технически правильным, это не объясняет, почему он решает проблему или должен быть выбранным ответом. Мы должны обучать вместе с помогая решить проблему.
Вместо for/loop
, создания элемента DOM, добавления к нему HTML и присоединения его к DOM, карта немного проще в использовании. Вы уже используете строку шаблона для создания HTML-кода, чтобы мы могли его вписать.
Примечание: вы должны посмотреть на ответ JSON, чтобы понять, как он составлен, чтобы вы могли правильно написать свой HTML. Например, data.name
не будет работать, потому что name
— это объект, содержащий свойство common
и свойство official
, поэтому вместо этого вам нужно получить одно из этих значений.
В этом примере я использовал async/await, так как его немного легче разбить на части и немного легче читать. Кроме того, я использовал только пару примеров в HTML — flag
, common
имя и population
.
// Cache the countries element
const countries = document.querySelector('.countries');
// Fetch the data. If there's an error in the response throw it,
// otherwise return the parsed JSON
async function getData() {
const res = await fetch('https://restcountries.com/v3.1/all');
if (!res.ok) throw new Error(`${res.status}: ${res.statusText}`);
return res.json();
}
// Accepts the parsed JSON it `map` over that array
// of objects, destructures the properties that will be
// used in the HTML, and returns the HTML for that
// object using a template string. Once the iteration is
// complete join the array of strings `map` returns
// into one single string
function buildCountries(data) {
return data.map(obj => {
const {
name: { common },
population,
flag
} = obj;
return `
<section class = "country">
<h4>${flag} ${common}</h4>
<p>${population}</p>
</section>
`;
}).join('');
}
// Get the data, get the HTML, and then add the HTML
async function main() {
try {
const data = await getData();
const html = buildCountries(data);
countries.insertAdjacentHTML('beforeend', html);
} catch (err) {
console.error(err.message);
}
}
main();
.country { background-color: #efefef; padding: 0.25em; border: 1px solid #dfdfdf; }
.country:not(:last-child) { margin-bottom: 0.25em; }
h4 { padding: 0; margin: 0; }
<div class = "countries"></div>
Дополнительная документация
«асинхронный» должен предшествовать «функции».