Toast Error Message not display on first component Mount

32 views Asked by At

So within my profile page I am displaying toast messages based on success of fetching the users profile, the success message works as intended as it has the loading to update the state then show the message but the issue occurs when the error message is to be displayed as because the error is caught so it will not reach the loading state but then even with the showError conditional rendering the issue is that it does not display the error message on first mount only when the page is refreshed for the 2nd time as the state is not in sync, how can I fix this so that the error message will also be shown on the first render?

Here is the component I am showing the messages within:

const UserProfile = () => {
  const dispatch = useDispatch();
  const location = useLocation();
  const navigate = useNavigate();
  const queryString = location.search;
  const urlParams = new URLSearchParams(queryString);
  const usernameFromParams = urlParams.get('username'); 
  const usernameFromState = location.state && location.state.username;
  const qr_id = location.state?.qr_id;
  const username = usernameFromParams || usernameFromState;
  const viewParam = urlParams.get('view');
  const profileData = useSelector(state => state.profile.data);
  const isLoading = useSelector(state => state.profile.isLoading);
  const [isNavigatedByApp, setIsNavigatedByApp] = useState(false) // state to track navigation intitiated by app 
  const [showError, setShowError] = useState(false); // error message state for toast message
  const [showSuccess, setShowSuccess] = useState(false) // success message state for toast message

  useEffect(() => {
    const fetchProfile = async () => {
      try {
  
        // Check if navigation was initiated by the app, useNavigate hook or by direct URL manipulation
        if (isNavigatedByApp || location.state || usernameFromParams) { // checks if by app or useNavigate hook 
          // location.state only set when useNavigate hook used
          console.log("navigated by app ")
          if (username) {
            await dispatch(fetchProfileByUsername(username));
            setShowSuccess(true);
            showToastSuccess(`User ${username} logged in! not with local storage`);
            localStorage.setItem('username', username); // set username in local storage
          } else if (qr_id) {
            await dispatch(fetchProfileByQrId(qr_id));
            setShowSuccess(true);
            showToastSuccess(`User logged in with qr_id ${qr_id}`)
            localStorage.setItem('qr_id', qr_id);  // Set the qr_id in local storage
          } else {
            console.error("Neither User nor qr_id is defined");
            setShowError(true);
            showToastError("Neither Username nor qr_id is defined");
          }
        } else {
          // If navigation was not initiated by the app, fetch data from local storage
          const storedUsername = localStorage.getItem('username');
          const storedQrId = localStorage.getItem('qr_id');
          if (storedUsername) {
            await dispatch(fetchProfileByUsername(storedUsername));
            setShowSuccess(true);
            showToastSuccess(`User ${storedUsername} Logged In! with localStorage`)
          } else if (storedQrId) {
            await dispatch(fetchProfileByQrId(storedQrId));
            setShowSuccess(true);
            showToastSuccess(`User logged in through qr_id ${storedQrId}`);
          } else {
            console.error("Neither User nor qr_id is stored in local storage");
            setShowError(true);
            showToastError("Neither Username nor qr_id is defined");
          }
        }
      } catch (error) {
        console.error('Error fetching profile:', error);
        setShowError(true);
        showToastError('Error fetching profile');
      }
      console.log("show error state = ", showError)
    };
    fetchProfile();
  }, [dispatch, username, qr_id, isNavigatedByApp]);
  


  return (
    <div >
      <SiteNavigation  setIsNavigatedByApp={setIsNavigatedByApp} />
      {showError && <ToastMessage />}
      {isLoading || !profileData ? (
        
        <p>Loading...</p>
      ) : ( 
        <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100vh' }}>
           <ToastMessage />
          <div>
            <h2>{profileData.username}'s Profile</h2>
            <p>Username: {profileData.username}</p>
            <p>Email: {profileData.email}</p>
            <p>Bio: {profileData.bio}</p>
          </div>

        </div>
      )}
    </div>
  );
};

export default UserProfile;

Here is my toastMessage component:

import React from 'react';
import { Bounce, ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';

const ToastMessage = () => {
  return (
    <ToastContainer />
  );
};

export const showToastSuccess = (message) => {
  toast.success(message);
};

export const showToastError = (message) => {
    console.log("toast error message ", message);
  toast.error(message, {
    position: "top-right",
    autoClose: 5000,
    hideProgressBar: false,
    closeOnClick: true,
    pauseOnHover: true,
    draggable: true,
    progress: undefined,
    theme: 'light',
    transition: Bounce,
  });
};

export default ToastMessage;
0

There are 0 answers