0

I have this link https://api.covid19api.com/countries, which holds the "Country", "Slug", and "ISO2" of several countries. I want to display, only the "Country" value in tag.I wrote the following code


function App() {

  const [countries,setCountries] = React.useState();

  React.useEffect(()=>{
    async function fetchData(){
      const data = fetch('https://api.covid19api.com/countries').then(resp => resp.json());
      setCountries(data)
    }
    fetchData();
  },[])

  if(!countries){
    return(
      <h3>Loading.....</h3>
    )
  }

  return (
    <div>
        {
          countries.map(() => <h1>{countries.Country}</h1>)
        }
    </div>
  );
}

export default App;

but, it was giving the following error

TypeError: countries.map is not a function

Could anyone please say the correct way to do it

1
  • 1
    Probably because countries does not exist yet during rendering. Do something like countries && countries.ma(...). You can do a console.log just before the return at one point countries will be undefined then will later be defined after the API request is done. Commented Jun 6, 2020 at 19:07

3 Answers 3

2

I think you're just missing an await before setCountries.

const data = await fetch('https://api.covid19api.com/countries').then(resp => resp.json());
      setCountries(data)

Also, I think, it's better to initialise countries with an empty array here in this case.

const [countries,setCountries] = React.useState([]);

Sign up to request clarification or add additional context in comments.

1 Comment

That is only one of the problems. No default empty array is another as well as incorrect use of map()
2

3 issues

1 => You are not using await

2 => You are not passing any parameter in the map method

3 => Response is an array, So you need to make your state an array.

Updated Code.

function App() {

  const [countries,setCountries] = React.useState([]);

  React.useEffect(()=>{
    async function fetchData(){
      const data = await fetch('https://api.covid19api.com/countries').then(resp => resp.json());
      setCountries(data)
    }
    fetchData();
  },[])

  if(!countries){
    return(
      <h3>Loading.....</h3>
    )
  }

  return (
    <div>
        {
          countries.map((data) => <h1>{data.Country}</h1>)
        }
    </div>
  );
}

export default App;

4 Comments

Third issue is countries is not an array on initial render. Modifying to React.useState([]); would set empty array as default
You are right , I just checked the API. Let me fix that
@RahulDwivedi Setting empty array as default value for countries solves that
@RahulDwivedi I mean setting default using React.useState([]);. Syntax you used makes no sense
-1

You have had await keyword with async. The word 'async' before a function means one simple thing: a function always returns a promise and the keyword await makes JavaScript wait until that promise settles and returns its result. So it will be something like this

React.useEffect(() => {
    async function fetchData() {
      const data = await fetch("https://api.covid19api.com/countries").then(
        resp => resp.json()
      );
      setCountries(data);
    }
    fetchData();
  }, []);

This is my codesandbox link if wanna check - https://codesandbox.io/s/cocky-lewin-7wwn9

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.