I'm trying to get a list of countries from an API and this is how I'm doing it.
useEffect(() => {
const getCountriesList = async () => {
const response: CovidInfo[] = await getCountries();
console.log(response.length)
let countryList = response.map((country: CovidInfo) => ({
name: country.name,
iso2: country.iso2,
iso3: country.iso3,
}));
countryList.unshift({name: "Global", iso2: "Global", iso3: "Global"});
setCountries(countryList);
setCountry("Global");
};
getCountriesList();
}, []);
My code compiles and builds but at runtime it tells me that response.map is not a function and when I try to log the length of the list it returns undefined. I can't seem to figure out why the response variable is not being recognised as a list. Below, I have also added what CovidInfo and getCountries looks like
export interface CovidInfo {
name: string;
iso2: string;
iso3: string;
confirmed: {value: number; detail: string;};
recovered: {value: number; detail: string;};
deaths: {value: number; detail: string;};
};
const getCountries = async () => {
try {
const response = await fetch("https://covid19.mathdro.id/api/countries");
const data = await response.json();
return data;
} catch (error) {
console.log(error);
return [];
}
};
Check the API: https://covid19.mathdro.id/api/countries
I can see the response format is:
{
countries: [
{ name: 'Afghanistan', iso2: 'AF', iso3: 'AFG' },
...,
]
}
So when your getCountries
returns response.json()
it's returning an object, not an array. That is why length
is undefined and map
is not a function.
The list of countries you want is inside the property countries
.
For it to work you can change your code to something like:
console.log(response.countries.length)
let countryList = response.countries.map((country: CovidInfo) => ({
name: country.name,
iso2: country.iso2,
iso3: country.iso3,
}));