Shruti sharma
Shruti sharma

Reputation: 211

TypeError: Cannot read properties of undefined (reading 'map')( Existing solution dint help)

I have checked other answers but that dint help.

I am not able to understand why this error is coming. I have checked api by running postman and it is giving proper data. Also I have checked my variables. what could be the possible reason for this error. below is the code.

const RestaurentList = () => {
      const {restaurants , setRestaurents } = useContext(RestaurentsContext)
      useEffect(async () => {
          const fetchData= async ()=>{
              try{
                  const response = await RestaurentFinder.get("/")
                  setRestaurents(response.data.restaurants)
                  console.log(response);
              }catch(err) { }
          };
        fetchData();
      }, [])
   
    return (
        <div className="list-group">
            <table className="table table-hover table-dark">
               <thead>
                   <tr className="bg-primary">
                      <th scope="col">Restaurent </th>
                      <th scope="col">Location</th>
                      <th scope="col">Price Range</th>
                      <th scope="col">Ratings</th>
                      <th scope="col">Edit</th>
                      <th scope="col">Delete</th>
                   </tr>
               </thead>
               <tbody>
                   {restaurants.map((restaurant)=>{
                       return (
                           <tr>
                               <td>{restaurant.name}</td>
                               <td>{restaurant.location}</td>
                               <td>{"$".repeat(restaurant.price_range)}</td>
                               <td>{restaurant.reviews}</td>
                               <td>
                               <button className="btn btn-warning">Update</button>
                               </td>
                               <td>
                               <button className="btn btn-danger">Delete</button> 
                               </td>
                               
                           </tr>
                       );                       
                         })}             
               </tbody>
            </table>
        </div>
    )
}
export default RestaurentList

output of API:-

{
    "status": "Success",
    "results": 1,
    "data": {
        "restaurants": [
            {
                "id": "1",
                "name": "Mcdonalds",
                "location": "Hyderabad",
                "price_range": 3
            }
        ]
    }
}

this is the error I am getting. enter image description here

Upvotes: 0

Views: 770

Answers (3)

Muhammad Junaid Aziz
Muhammad Junaid Aziz

Reputation: 134

If you are using axios as HTTP module:

 const {response : { data : { restaurants } }} = await
    RestaurentFinder.get("/");
    setRestaurents(restaurants);

If You are using Fetch

 const response  = await RestaurentFinder.get("/");
 const {response : { data : { restaurants } }} = await response.json();
    setRestaurents(restaurants);

Upvotes: 1

What is initial value for restaurants? Your request is asynchronous, but the render is not. You need to wait for data to be fetched. One way to do it is to show some spinner:

const { restaurants, setRestaurents, loading, setLoading } =
  useContext(RestaurentsContext);

useEffect(async () => {
  const fetchData = async () => {
    setLoading(true);

    try {
      const response = await RestaurentFinder.get("/");

      setRestaurents(response.data.restaurants);
    } catch (err) {
    } finally {
      setLoading(false);
    }
  };
  fetchData();
}, []);

if (loading) {
  return <span>Loading...</span>
}

or you can have default value for restaurants - [] or just check for undefined:

{restaurants?.map(/* ... */)}

Upvotes: 1

hurricane
hurricane

Reputation: 6724

So response.data is the object coming from your fetch tool (axios prob.). You need to reach the restaurants like this;

const response = await RestaurentFinder.get("/");
const restaurantResult = response.data;
setRestaurents(restaurantResult.data.restaurants);

Upvotes: 1

Related Questions