Search code examples
javascriptreactjsredux

How to redirect to NotFound page if profile ID does not exist?


I want to redirect user to NotFound page if he request the address localhost:3000/profile/*any unexisting id*. Currently a have a similar route for any incorrect address on localhost, but it does not work with incorrect IDs on routes /profile/:idand posts/:id (I can see only loadind without end). The code of profile component below is workable, but it obviously looks silly because I always get NotFound page instead of loading spinner, even on few seconds if ID is correct and profile exists:

import React, { Fragment, useEffect } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import Spinner from '../layout/Spinner';
import { getProfileById } from '../../actions/profile';
import { Link } from 'react-router-dom';
import ProfileTop from './ProfileTop';
import ProfileAbout from './ProfileAbout';
import ProfileExperience from './ProfileExperience';
import ProfileEducation from './ProfileEducation';
import ProfileGithub from './ProfileGithub';
import NotFound from '../layout/NotFound';

const Profile = ({ getProfileById, profile: { profile, loading }, auth, match }) => {
    useEffect(() => {
        getProfileById(match.params.id);
    }, [getProfileById, match.params.id]);
    
    if(profile === null ){
        return <NotFound />
    }

    return (
        <Fragment>
            {profile === null || loading ?  <Spinner /> : (<Fragment>
                <Link to='/profiles' className="btn btn-light">Back to profiles</Link>
                {auth.isAuthenticated && auth.loading === false && auth.user._id ===
                    profile.user._id && (<Link to="/edit-profile" className="btn btn-dark">
                        Edit profile</Link>)}

                <div className="profile-grid my-1">
                    <ProfileTop profile={profile} />
                    <ProfileAbout profile={profile} />
                    <div className='profile-exp bg-white p-2'>
                        <h2 className='text-primary'>Experience</h2>
                        {profile.experience.length > 0 ? (
                            <Fragment>
                                {profile.experience.map(experience => (
                                    <ProfileExperience key={experience._id} experience={experience} />))}
                            </Fragment>
                        ) : (
                            <h4>No experience credentials</h4>
                        )}
                    </div>

                    <div className='profile-edu bg-white p-2'>
                        <h2 className='text-primary'>Education</h2>
                        {profile.education.length > 0 ? (
                            <Fragment>
                                {profile.education.map(education => (
                                    <ProfileEducation
                                        key={education._id}
                                        education={education}
                                    />
                                ))}
                            </Fragment>
                        ) : (
                            <h4>No education credentials</h4>
                        )}
                    </div>

                    {profile.githubusername && (
                        <ProfileGithub username={profile.githubusername} />
                    )}
                </div>
            </Fragment>)}
        </Fragment>
    )
};

The route on backend:

//Getting profile by id
router.get('/user/:user_id', async(req, res) => {
    try {
        const profile = await Profile.findOne({ user: req.params.user_id })
            .populate('user', ['name', 'avatar']);

        if (!profile) return res.status(400).json({ msg: 'There is no profile for this user' });
        res.json(profile);
    } catch (err) {
        console.error(err.message);
        if (err.kind == 'ObjectId') {
            return res.status(400).json({ msg: 'Profile not found' });
        }
        res.status(500).send('Server error');
    }
});

Routes:

const Routes = () => {
    return (
        <section className="container">
          <Alert />
            <Switch>
                <Route exact path='/register' component={Register} />
                <Route exact path='/login' component={Login} />
                <Route exact path='/profiles' component={Profiles} />
                <Route exact path='/profile/:id' component={Profile} />
                <PrivateRoute exact path='/dashboard' component={Dashboard} />
                <PrivateRoute exact path='/create-profile' component={CreateProfile} />
                <PrivateRoute exact path='/edit-profile' component={EditProfile} />
                <PrivateRoute exact path='/add-experience' component={AddExperience} />
                <PrivateRoute exact path='/add-education' component={AddEducation} />
                <PrivateRoute exact path='/posts' component={Posts} />
                <PrivateRoute exact path='/posts/:id' component={Post} />
                <Route component={NotFound} />
            </Switch>
        </section>
    );
}

Solution

  • Maybe not working for localhost but for server use htaccess or webconfig file