node.jsreactjsmernreact-fullstack

UseEffect() doesn't fetch my data from the api


I'm following a tutorial on a fullstack app. I'm trying to fetch my data from the API using useEffect(). I've followed the tutorial by heart and I'm stuck on this problem for some time and can't seem to find a fix to it. I've also used the Here is the code:

1)Here is the hook for fetching the data from the API.

import { useEffect, useState } from "react";
import axios from "axios";

const useFetch = (url) => {
  const [data, setData] = useState([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(false);
  useEffect(() => {
    const fetchData = async () => {
      setLoading(true);
      try {
        const res = await axios.get(url);
        setData(res.data);
      } catch (error) {
        setError(error);
      }
      setLoading(false);
    };
    fetchData();
  }, [url]);

  return { data, loading, error };
};

export default useFetch;

2)Here is the API

export const countByType = async (req, res, next) => {
  try {
    const hotelCount = await Hotel.countDocuments({ type: "Hotel" });
    const apartmentCount = await Hotel.countDocuments({ type: "apartment" });
    const resortCount = await Hotel.countDocuments({ type: "resort" });
    const villaCount = await Hotel.countDocuments({ type: "villa" });
    const cabinCount = await Hotel.countDocuments({ type: "cabin" });

    res.status(200).json([
      { type: "hotel", count: hotelCount },
      { type: "apartment", count: apartmentCount },
      { type: "resort", count: resortCount },
      { type: "villa", count: villaCount },
      { type: "cabin", count: cabinCount },
    ]);
  } catch (error) {
    next(createError(500, "Something went wrong"));
  }
};

3)Here I'm trying to use that data to render it on my page.

import useFetch from "../../hooks/useFetch.js";
import "../propertyList/propertyList.css";

const images = [
  "https://images.pexels.com/photos/189296/pexels-photo-189296.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
  "https://images.pexels.com/photos/189296/pexels-photo-189296.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
  "https://images.pexels.com/photos/189296/pexels-photo-189296.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
  "https://images.pexels.com/photos/189296/pexels-photo-189296.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
  "https://images.pexels.com/photos/189296/pexels-photo-189296.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
];

const propertyList = () => {
  const { data, loading, error } = useFetch(
    "//localhost:3000/api/hotels/countByType"
  );

  return (
    <div className="pList">
      {loading ? (
        "loading"
      ) : (
        <>
          {data &&
            images.map((img, i) => (
              <div className="pListItem">
                <img src="" alt="" className="pListImage" />
                <h1>{data[0].type}</h1>
                <span>{data[0].count}</span> <span>{data[0].type}</span>
              </div>
            ))}
        </>
      )}
    </div>
  );
};

export default propertyList;

Here are the photos with the error that I get. I don't think the first one is an error but i think it might help solve the issue. enter image description here

enter image description here


Solution

  • add null checks where you are using the data

    <div className="pList">
      {loading ? (
        "loading"
      ) : (
        <>
          {data && data.length > 0 &&
            images.map((img, i) => (
              <div className="pListItem">
                <img src="" alt="" className="pListImage" />
                <h1>{data[0]?.type}</h1>
                <span>{data[0]?.count}</span> <span>{data[0].type}</span>
              </div>
            ))}
        </>
      )}
    </div>