I'm having trouble to return a few keys from objects which are coming from promises callback function. The error I'm getting is on second country:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'png')
'use strict';
const btn = document.querySelector('.btn-country');
const countriesContainer = document.querySelector('.countries');
const renderCountry = function (data, className = '') {
const html = `
<article class="country ${className}">
<img class="country__img" src="${data.flags.png}" />
<div class="country__data">
<h3 class="country__name">${data.name.official}</h3>
<h4 class="country__region">${data.region}</h4>
<p class="country__row"><span></span> ${(
+data.population / 1000000
).toFixed(1)} millions people</p>
<p class="country__row"><span>️</span>${Object.values(
data.languages
)}</p>
<p class="country__row"><span></span>${Object.keys(data.currencies)}</p>
</article>`;
countriesContainer.insertAdjacentHTML('beforeEnd', html);
countriesContainer.style.opacity = 1;
};
const getCountryData = function (country) {
// Country 1
fetch(`https://restcountries.com/v3.1/name/${country}`)
.then(response => response.json())
.then(data => {
renderCountry(data[0]);
console.log(data);
const neighbour = data[0].borders[0];
if (!neighbour) return;
// Country 2
return fetch(`https://restcountries.com/v3.1/alpha/${neighbour}`);
})
.then(responce => responce.json())
.then(data => renderCountry(data, 'neighbour'));
};
getCountryData('portugal');
Here index if needed just that you can recreate:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<link rel="stylesheet" href="style.css" />
<script defer src="Asynchronous.js"></script>
<title>Asynchronous JavaScript</title>
</head>
<body>
<main class="container">
<div class="countries"></div>
<!-- <bn class="btn-country">Where am I?</button> -->
<div class="images"></div>
</main>
</body>
</html>
And CSS
* {
margin: 0;
padding: 0;
box-sizing: inherit;
}
html {
font-size: 62.5%;
box-sizing: border-box;
}
body {
font-family: system-ui;
color: #555;
background-color: #f7f7f7;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.container {
display: flex;
flex-flow: column;
align-items: center;
}
.countries {
/* margin-bottom: 8rem; */
display: flex;
font-size: 2rem;
opacity: 0;
transition: opacity 1s;
}
.country {
background-color: #fff;
box-shadow: 0 2rem 5rem 1rem rgba(0, 0, 0, 0.1);
font-size: 1.8rem;
width: 30rem;
border-radius: 0.7rem;
margin: 0 3rem;
/* overflow: hidden; */
}
.neighbour::before {
content: 'Neighbour country';
width: 100%;
position: absolute;
top: -4rem;
text-align: center;
font-size: 1.8rem;
font-weight: 600;
text-transform: uppercase;
color: #888;
}
.neighbour {
transform: scale(0.8) translateY(1rem);
margin-left: 0;
}
.country__img {
width: 30rem;
height: 17rem;
object-fit: cover;
background-color: #eee;
border-top-left-radius: 0.7rem;
border-top-right-radius: 0.7rem;
}
.country__data {
padding: 2.5rem 3.75rem 3rem 3.75rem;
}
.country__name {
font-size: 2.7rem;
margin-bottom: 0.7rem;
}
.country__region {
font-size: 1.4rem;
margin-bottom: 2.5rem;
text-transform: uppercase;
color: #888;
}
.country__row:not(:last-child) {
margin-bottom: 1rem;
}
.country__row span {
display: inline-block;
margin-right: 2rem;
font-size: 2.4rem;
}
.btn-country {
border: none;
font-size: 2rem;
padding: 2rem 5rem;
border-radius: 0.7rem;
color: white;
background-color: orangered;
cursor: pointer;
}
.images {
display: flex;
}
.images img {
display: block;
width: 80rem;
margin: 4rem;
}
.images img.parallel {
width: 40rem;
margin: 2rem;
border: 3rem solid white;
box-shadow: 0 2rem 5rem 1rem rgba(0, 0, 0, 0.1);
}
I tried methods which obviously don't work, so maybe you can spot and error and point it out!