Reputation: 169
Would anyone be able to help me with this error? I am trying to create a drop down picker for country names, pulling from the following API path: https://api.covid19api.com/countries
TypeError: Country.map is not a function
at fetchCountries (index.js:29)
at async fetchAPI (CountryPicker.jsx:13)
Here are the two code sections I am working in:
CountryPicker.jsx
import React, { useState, useEffect } from 'react';
import { NativeSelect, FormControl } from '@material-ui/core';
import styles from './CountryPicker.module.css';
import { fetchCountries } from '../../api';
const CountryPicker = () => {
const [fetchedCountries, setFetchedCountries] = useState([]);
useEffect(() => {
const fetchAPI = async () => {
setFetchedCountries(await fetchCountries());
};
fetchAPI();
}, [setFetchedCountries]);
console.log(fetchedCountries);
return (
<FormControl className={styles.formControl}>
<NativeSelect >
<option value="">Global</option>
</NativeSelect>
</FormControl>
);
};
export default CountryPicker;
index.js
import axios from 'axios';
const summary = 'https://api.covid19api.com/summary';
const countriesURL = 'https://api.covid19api.com/countries';
export const fetchData = async () => {
try {
const { data: { Global: { NewConfirmed, TotalConfirmed, NewDeaths, TotalDeaths, NewRecovered, TotalRecovered, }, Date } } = await axios.get(summary);
return { NewConfirmed, TotalConfirmed, NewDeaths, TotalDeaths, NewRecovered, TotalRecovered, Date };
} catch (error) {
console.log(error);
}
}
//TODO
//Fetch Daily Data for charts using axios
export const fetchCountries = async () => {
try {
const { data: [ {Country} ] } = await axios.get(countriesURL);
return Country.map((Country) => Country);
} catch (error) {
console.log(error);
}
};
I tried to look up why the error may be happening and I found that .map() will not work on a variable that is not an array, but I'm unsure with the current implementation, how to fix this
The data from the API looks like this:
[
{"Country":"Micronesia, Federated States of","Slug":"micronesia","ISO2":"FM"},
{"Country":"Bangladesh","Slug":"bangladesh","ISO2":"BD"},
{"Country":"Bouvet Island","Slug":"bouvet-island","ISO2":"BV"},
// ...and so on...
]
Upvotes: 0
Views: 82
Reputation: 8125
The restructure is not properly handled here.
const { data: [ x ] } = {data: [{"Country":"Micronesia, Federated States of","Slug":"micronesia","ISO2":"FM"},{"Country":"Bangladesh","Slug":"bangladesh","ISO2":"BD"}]}
Here x
will be {"Country":"Micronesia, Federated States of","Slug":"micronesia","ISO2":"FM"}
Next:
const {Country} = x
Here Country will be "Micronesia, Federated States of"
and "Micronesia, Federated States of"
is a string and it does not have map
function.
So{ data: [ {Country} ] }
is wrong way to access all keys.
const fetchCountries = async () => {
try {
const countries = await axios
.get(countriesURL)
.then((x) => x.data);
return countries.map(({ Country }) => Country);
} catch (error) {
console.log(error);
return []
}
};
const fetchCountries = async () => {
try {
const countries = await axios
.get("https://api.covid19api.com/countries")
.then((x) => x.data);
return countries.map(({ Country }) => Country).sort();
} catch (error) {
console.log(error);
return []
}
};
fetchCountries().then(console.log);
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.min.js"></script>
Fetch other info:
// const axios = require("axios"); // for node js
const fetchCountriesInfoParallel = async (countries = []) => {
const promises = countries.map((country) =>
axios
.get(`https://api.covid19api.com/live/country/${country}`)
.then(({ data }) => data)
);
try {
return await Promise.all(promises);
} catch (error) {
console.log(error);
return [];
}
};
fetchCountriesInfoParallel(["Afghanistan", "Albania", "Algeria"]).then(
console.log
);
const fetchCountriesInfoSeries = async (countries = []) => {
let results = [];
for (let index = 0; index < countries.length; index++) {
const country = countries[index];
const data = await axios
.get(`https://api.covid19api.com/live/country/${country}`)
.then(({ data }) => data);
results.push(data);
}
return results;
};
fetchCountriesInfoSeries(["Afghanistan", "Albania", "Algeria"]).then(
console.log
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.min.js"></script>
Upvotes: 1
Reputation: 1074168
Looking at the result of calling the API, it's in this form:
[
{"Country":"Micronesia, Federated States of","Slug":"micronesia","ISO2":"FM"},
{"Country":"Bangladesh","Slug":"bangladesh","ISO2":"BD"},
{"Country":"Bouvet Island","Slug":"bouvet-island","ISO2":"BV"},
// ...and so on...
]
So Country
isn't an array, it's a property of each object in the array.
If your goal is to extract the Country
property from each object, take the array and then use map
extracting that property, perhaps with destructuring:
const data = await axios.get(countriesURL);
return data.map(({Country}) => Country);
Upvotes: 3