0

I have an issue with my code, i have a search input and a list of countries

When i type some words i have an error which cause to my app collapse

I've been trying for about two days to find the problem but can't find it.

This is the error message : Uncaught TypeError: Cannot read properties of undefined (reading 'filter')

const Country = ({name, num}) =>{
//console.log(name)  
return (
    <div>
        <p>{name}</p>
    </div>
)} // Component

const Input = ({onSearch, search}) =>{

return (
    <div>
        Find countries: <input onChange={onSearch} value={search} />
    </div>
)} // Component

    import { useState, useEffect } from "react";
import axios from "axios";
import Input from "./components/Input";
import Country from "./components/Country";
const App = () => {
  const [countryList, setCountryList] = useState();
  const [search, setSearch] = useState("");
  const [filter, setFilter] = useState(false);
  useEffect(() => {
    axios
      .get("https://restcountries.com/v3.1/all")
      .then((res) => setCountryList(res.data));
  }, []);
  const onSearch = (event) => {
    if (event.target.value === " ") setFilter(false);
    else {
      setFilter(true);
      setSearch(event.target.value);
    }
  };

  const countriesList = filter 
    ? countryList.filter((country) => {
        return country.name.common.includes(search);
      })
    : null ;

  return (
    <div>
      <Input onSearch={onSearch} search={search} />
      {filter ? (
        countriesList.length === 0 ? (
          <h3>No match</h3>
        ) : countriesList.length > 10 ? (
          <h3>Too many matches, specify another filter...</h3>
        ) : countriesList.length < 10 && countriesList.length > 1 ? (
          countriesList.map((country, i) => (
            <Country name={country.name.common} key={i} num={false} />
          ))
        ) : (
          <Country name={countriesList[0].name.common} num={true} /> &&
          console.log("common", countriesList)
        )
      ) : (
        <h3>Search for any country</h3>
      )}
    </div>
  );
};
1
  • 1
    useEffect is executed only after the component has been rendered therefore, at the very beginning, countryList is undefined and countryList.filter will give you that error. One way to avoid it is to initialize countryList to an empty array (const [countryList, setCountryList] = useState([]);) Commented Oct 28, 2022 at 10:31

2 Answers 2

1

countrylist state must be an array.

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

Comments

1

Try using array in countyList as its undefined initially

const [countryList, setCountryList] = useState([]);

Also you seems to be you accessing filter (a state value directly while component initilize). Please try replacing with below code. Let me know if issue persists, should be a very simple fix

    const [countriesList, setCountriesList] = useState([]);
    useEffect(()=>{
            if(filter){
                setCountriesList(
                   countryList.filter((country) => {
                   return country?.name?.common?.includes(search);
                }))
             }else{
                setCountriesList(countryList);
             }
    },[filter])
    

3 Comments

But the useEffect only execute once right ?
Yes, if you want to trigger it based on the filter then you can add a dependency, edited the answer.
Edited: So whenever filter will change then useEffect will ve executed. I guess this fixes all for you. If so, please mark it as answered.

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.