React Frontend Not Displaying Content After Successful Fetch from API

Hi all,

I’m facing an issue in my React project. I have implemented a fetch request to an API, and the data is being successfully retrieved. However, the content isn’t being displayed in the frontend.

Here’s a summary of the issue:

  1. The fetch request successfully gets data from the API.
  2. The data is stored in the component’s state.
  3. Despite updating the state, the frontend doesn’t reflect the changes, and nothing is shown.

Steps I’ve taken:

  • Checked the network tab, and the API response is fine (status 200).
  • Verified the state is being updated correctly in React.
  • Tried using both useEffect and useState to manage the data, but the display still doesn’t work.
const User = require("../models/userModel");
const Admin = require("../models/adminModel");
const bcrypt = require("bcrypt");

module.exports.register = async (req, res, next) => {
  try {
    const { username, email, password, isAdmin } = req.body;

    const usernameExists =
      (await User.findOne({ username })) || (await Admin.findOne({ username }));
    if (usernameExists) {
      return res.status(400).json({ message: "Username already exists" });
    }

    const emailExists =
      (await User.findOne({ email })) || (await Admin.findOne({ email }));
    if (emailExists) {
      return res.status(400).json({ message: "Email already exists" });
    }

    const hashedPassword = await bcrypt.hash(password, 10);
    let account;
    if (isAdmin) {
      account = new Admin({ username, email, password: hashedPassword });
    } else {
      account = new User({ username, email, password: hashedPassword });
    }
    await account.save();
    const { password: _, ...responseAccount } = account._doc;

    return res.status(201).json({
      status: true,
      message: isAdmin
        ? "Admin registered successfully"
        : "User registered successfully",
      account: responseAccount
    });
  } catch (error) {
    next(error);
  }
};

module.exports.login = async (req, res, next) => {
  try {
    const { username, password, isAdmin } = req.body;

    const account = isAdmin
      ? await Admin.findOne({ username })
      : await User.findOne({ username });
    if (!account) {
      return res
        .status(400)
        .json({ status: false, message: "Invalid Username" });
    }

    // Validate password
    const isValidPassword = await bcrypt.compare(password, account.password);
    if (!isValidPassword) {
      return res
        .status(400)
        .json({ status: false, message: "Invalid Password" });
    }

    // Omit sensitive data
    const { password: _, ...accountDetails } = account._doc;
    return res.status(200).json({
      status: true,
      message: "Login Successful",
      account: accountDetails
    });
  } catch (error) {
    next(error);
  }
};

module.exports.setavatar = async (req, res, next) => {
  try {
    const userId = req.params.id;
    const avatarImage = req.body.image;
    if (!userId || !avatarImage) {
      return res.status(400).json({ message: "Invalid user ID or image data" });
    }
    const userData = await User.findByIdAndUpdate(
      userId,
      { isAvatarImageSet: true, avatarImage },
      { new: true }
    );

    if (!userData) {
      return res.status(400).json({ error: "User not found" });
    }
    console.log("Updating user:", userId, "with avatar:", avatarImage);
    console.log("Updated User Data:", userData);

    return res.json({
      isSet: userData.isAvatarImageSet,
      image: userData.avatarImage
    });
  } catch (error) {
    console.error("Error setting avatar:", error);
    next(error);
  }
};

module.exports.setAvatarAdmin = async (req, res, next) => {
  try {
    const adminId = req.params.id;
    const avatarImage = req.body.image;
    if (!adminId || !avatarImage) {
      return res.status(400).json({ message: "Invalid user ID or image data" });
    }
    const userData = await Admin.findByIdAndUpdate(
      adminId,
      { isAvatarImageSet: true, avatarImage },
      { new: true }
    );

    if (!userData) {
      return res.status(400).json({ error: "User not found" });
    }
    console.log("Updating user:", adminId, "with avatar:", avatarImage);
    console.log("Updated User Data:", userData);

    return res.json({
      isSet: userData.isAvatarImageSet,
      image: userData.avatarImage
    });
  } catch {
    console.error("Error Admin setting avatar:", error);
    next(error);
  }
};

module.exports.getusers = async (req, res, next) => {
  console.log("Fetching users for ID:", req.params.id);
  const { id } = req.params;
  try {
    const users = await User.find({ _id: { $ne: id } }).select([
      "email",
      "username",
      "avatarImage",
      "_id"
    ]);
    if (!users) {
      return res.status(400).json({ error: "No users found" });
    }
    return res.status(200).json({ data: users });
  } catch (error) {
    console.error("Error fetching users:", error);
    return res.status(500).json({ error: "Server Error" });
    next(error);
  }
};

module.exports.getAdmins = async (req, res, next) => {
  const { id } = req.params;
  try {
    const admins = await Admin.find({ _id: { $ne: id } }).select([
      "email",
      "username",
      "avatarImage",
      "_id"
    ]);
    if (!admins || admins.length === 0) {
      return res.status(404).json({ message: "No admins found" });
    }
    return res.status(200).json({ data: admins });
  } catch (error) {
    next(error);
  }
};

import React, { useEffect, useState } from "react";
import UserContainer from "../components/UserContainer";
import AdminContainer from "../components/AdminContainer";
import { useNavigate } from "react-router-dom";
import axios from "axios";
import { allAdminRoute, allUserRoute } from "../utils/APIRoutes";

const Chat = () => {
  const navigate = useNavigate();
  const [admins, setAdmins] = useState([]);
  const [users, setUsers] = useState([]);
  const [currentUser, setCurrentUser] = useState(null);
  const [currentAdmin, setCurrentAdmin] = useState(null);
  const [loading, setLoading] = useState(true);
  const [currentChat, setCurrentChat] = useState(undefined);

  useEffect(() => {
    const fetchStored = async () => {
      try {
        const storedData = localStorage.getItem("chat-app-user");
        console.log("Stored data:", storedData);

        if (!storedData) {
          navigate("/login");
          return;
        }

        const parsedData = JSON.parse(storedData);
        setCurrentUser(parsedData?.user || null);
        setCurrentAdmin(parsedData?.admin || null);
      } catch (error) {
        console.error("Error parsing local storage data:", error.message);
        navigate("/login");
      }
    };

    fetchStored();
  }, [navigate]);

  useEffect(() => {
    const fetchContacts = async () => {
      if (!currentUser && !currentAdmin) {
        setLoading(false);
        return;
      }

      setLoading(true);
      try {
        if (currentUser?._id) {
          const userResponse = await axios.get(
            `${allUserRoute}/${currentUser._id}`
          );
          setUsers(userResponse.data.data || []);
        }

        if (currentAdmin?._id) {
          const adminResponse = await axios.get(
            `${allAdminRoute}/${currentAdmin._id}`
          );
          console.log("Admin response:", adminResponse.data);
          setAdmins(adminResponse.data.data || []);
        }
      } catch (error) {
        console.error("Error fetching contacts:", error.message);
      } finally {
        setLoading(false);
        if (!currentUser?.isAvatarImageSet) {
          navigate("/Avatar");
        }
      }
    };

    fetchContacts();
  }, [navigate, currentUser, currentAdmin]);

  const handleChatChange = (chat) => {
    setCurrentChat(chat);
  };

  return (
    <div className="bg-gray-400 h-screen flex flex-col justify-between">
      {loading ? (
        <div className="text-center text-white font-bold text-lg">
          Loading...
        </div>
      ) : (
        <>
          {admins.length > 0 ? (
            <AdminContainer
              admins={admins}
              currentAdmin={currentAdmin}
              currentChat={handleChatChange}
            />
          ) : (
            <div className="text-center text-gray-500">No Admins Found</div>
          )}

          {users.length > 0 ? (
            <UserContainer
              users={users}
              currentUser={currentUser}
              currentChat={handleChatChange}
            />
          ) : (
            <div className="text-center text-gray-500">No Users Found</div>
          )}
        </>
      )}
    </div>
  );
};

export default Chat;

hello and welcome to fcc forum :slight_smile:

can you see that state data in browser console?

  • does that mean you could see your state data in browser? in that case check right before “rendering component” if data is being sent through props correctly

happy coding :slight_smile:

Do you really want navigate as a useEffect dependency? Considering it is a function that doesn’t seem right.

Are you sure currentUser and currentAdmin are both getting set to truthy values? Did you check the API response as part of rendering the component?

What is rendered? Surely some of your fallback JSX is rendering?


Post a repo with your code.