Fabio
Fabio

Reputation: 39

React Redux : TypeError: Cannot read property 'user' of null

I am trying to create Profile page to show specifc data for single user . the problem when I want to get the profile state using connect it returns to null !! the profile state should have the payload from the backend

in Profile.js


const Profile = ({ getProfileById, profile: { profile }, auth, match }) => {
  console.log(profile);
  useEffect(() => {
    
    getProfileById(match.params.id);
  }, [getProfileById, match.params.id]);
console.log(profile);
    return (
        <Fragment>
            {profile === null ? (<Spinner/>) : (<Fragment>
                <Link to="/Profiles" className="btn btn-light">
            Back To Profiles
          </Link>
                 </Fragment>)}

                 {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">
            
// when I pass profile as prop returns null
         <ProfileTop profile={profile} />
             </div>
        </Fragment>
    )
}

Profile.propTypes = {
getProfileById : PropTypes.func.isRequired,
profile : PropTypes.object.isRequired,
auth : PropTypes.object.isRequired,
}

const mapStateToProps = (state) => ({
  profile: state.profile,
  auth: state.auth
});
export default connect(mapStateToProps,{getProfileById}) (Profile)

in ProfileTop.js



const ProfileTop = ({profile : {
// Here showes the error ×
//TypeError: Cannot read property 'company' of null
    company,
    location,
    social,
    user : {name,avatar}
}}) => {
    return (
        <div className="profile-top bg-primary p-2">
        <img
          src={avatar}
          alt=""
          className="round-img"
        />
      </div>
    )
}

ProfileTop.propTypes = {
    profile : PropTypes.object.isRequired,

}

export default ProfileTop

note : Before I add The functionality when I see redux dev tools the profile does not equal null

here's getProfileById Action ..

export const getProfileById = userId => async dispatch => {
    try {
      const res = await axios.get(`/profile/user/${userId}`);
  
      dispatch({
        type: GET_PROFILE,
        payload: res.data
      });
    } catch (err) {
        console.log(err);
      dispatch({
        type: PROFILE_ERROR,
        payload: { msg: err.response.statusText, status: err.response.status }
      });
    }
  };

the initial State ..

const initialState = {

    profile : null,
    profiles : [],
    repos : [],
    loading : true ,
    error : {}
}

the GET_PROFILE Reducer

case GET_PROFILE : 
return {...state,
    profile : payload,
    loading : false
}

Upvotes: 0

Views: 336

Answers (2)

Fabio
Fabio

Reputation: 39

Ooopes guys I solved the problem It was because the closing tag of the Fragment I did not notice that 😅 today's lesson don't code when you have stayed up for more then 20 hours ..

return (
        <Fragment>
            {profile === null ? (<Spinner/>) : (<Fragment>
                <Link to="/Profiles" className="btn btn-light">
            Back To Profiles
          </Link>
// here I close the fragment normally profile will returns null
// I should close it right after the closing div
                 </Fragment>)}

                 {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} />
             </div>
        </Fragment>
    )
}

Upvotes: 1

Dan
Dan

Reputation: 26

Profile must get the data from action.payload and not from payload.

return {
    ...state,
    profile : action.payload,
    loading : false
}

Upvotes: 0

Related Questions