Simple question guys , why is response.ok always true, I want to practice throw new Error but this is a problem I can't fix... It seems I can click the button and the stuff works but I want to create a fake error and see how that goes please help :)
const btn = document.querySelector('.btn-country');
const countriesContainer = document.querySelector('.countries');
const renderError = function (msg) {
countriesContainer.insertAdjacentText('beforeend', msg);
// countriesContainer.style.opacity = 1;
};
const renderCountry = (data, className = '') => {
const html = ` <article class="${className}">
<img class="country__img" src="${data.flags.png}" />
<div class="country__data">
<h3 class="country__name">${data.name}</h3>
<h4 class="country__region">${data.region}</h4>
<p class="country__row"><span>👫</span>${(
+data.population / 1000000
).toFixed(1)} M</p>
<p class="country__row"><span>🗣️</span>${data.languages[0].name}</p>
<p class="country__row"><span>💰</span>${data.currencies[0].name}</p>
</div>
</article> `;
countriesContainer.insertAdjacentHTML('beforeend', html);
// countriesContainer.style.opacity = 1;
};
const getCountryData = function (country) {
fetch(`https://restcountries.com/v2/name/${country}?fullText=true`)
.then(response => {
console.log(response);
if (!response.ok) throw new Error(`AAAAAAA`);
return response.json();
})
.then(data => {
renderCountry(data[0]);
//neigbour code
// const neighbour = data[0].borders[0];
const neighbour = 'asdasd';
// if (!neighbour) return;
return fetch(`https://restcountries.com/v2/alpha/${neighbour}`);
})
.then(response => {
console.log(response);
return response.json();
})
.then(data => {
console.log(data);
renderCountry(data, 'neighbour');
})
.catch(err => {
renderError(`${err.message}`);
})
.finally(() => {
countriesContainer.style.opacity = 1;
});
};
btn.addEventListener('click', function () {
getCountryData('portugal');
});
getCountryData('asdasd');
That is because the value response.ok depends on whether the response status code is within the range of 200–299. It will be false for codes outside this range.
The endpoint you are accessing is badly designed in the sense that even when an invalid country is provided, it responds with a HTTP 200 status code but the payload contains the actual error code... while most developers would expect an error code being emitted.
In other words, it isn't really you doing something wrong: it is natural to expect that if a query fails or is invalid, you should exepect a non 2xx HTTP status code from an endpoint. However, the endpoint in question violates that expectation and always return 200 regardless of the outcome.
Therefore, if you want to catch the error, you will need to parse the response body and check if it is an object, and if it contains the status key. Based on my primitive testing, it seems that:
The endpoint returns an array of objects if a valid country name is used
The endpoint returns an object that matches the following interface, if an invalid country name is used:
{
status: number;
message: string;
}
For example:
{
"status": 404,
"message": "Not Found"
}
A proof-of-concept example below:
function fetchCountry(country) {
fetch(`https://restcountries.com/v2/name/${country}?fullText=true`)
.then(response => {
if (!response.ok) throw new Error(`AAAAAAA`);
return response.json();
})
.then(data => {
console.log(data);
if (data && 'status' in data) {
throw new Error(data.message);
}
})
.catch(e => {
console.error(e);
});
}
document.querySelector('#valid-country').addEventListener('click', () => fetchCountry('US'));
document.querySelector('#invalid-country').addEventListener('click', () => fetchCountry('FooBar'));
<button type="button" id="valid-country">Fetch using valid country name (US)</button>
<button type="button" id="invalid-country">Fetch using invalid country name (FooBar)</button>
You've misunderstood what response.ok means. From the reference:
The ok read-only property of the Response interface contains a Boolean stating whether the response was successful (status in the range 200-299) or not.
That is referring to the HTTP status code. Which implies that even when you use the wrong country, the server is still responding correctly. (most likely with nothing or an error returned.