Akhil Rana
Akhil Rana

Reputation: 155

TypeError: Cannot read property 'name"' of undefined in react when passing object in useState

My issue is from route getting the response in json format. And when consoling it gives the data as well but when i passing in setProfileData(data) then updated state gives undefined.

But when i gives like setProfileData(data.user.name) then its gives that specific value.

Here my server route

router.get('/user/:id',async(req,res)=>{
  try {
    const user = await User.findOne({_id:req.params.id}).select('-password')
    const post = await Post.find({postedBy:req.params.id}).populate('postedBy', '_id name')
    
    return res.json({user,post})
        
    } catch (error) {
        return res.json(error)
    }
})

Here is my Component UserProfile

import React,{useContext,useEffect,useState} from 'react';
import {useHistory,useParams} from 'react-router-dom'
import {UserContext} from '../../App'

const UserProfile = ()=>{
    const [newProfile,setProfileData] = useState(null)
    const {state,dispatch} = useContext(UserContext)
    
    const {userId} = useParams()
    console.log(userId)
    useEffect(()=>{
        fetch(`/user/${userId}`,{
            headers:{
                'Authorization': 'Bearer '+localStorage.getItem('jwt')
            }
        }).then((res)=>{
            return res.json()
        }).then((data)=>{
            console.log(data)
           setProfileData(data)
            
        })
    },[])
    return (
        <div style={{width:'555px',margin:"0px auto"}}>
            <div style={{display:"flex",justifyContent:"space-around",margin:'18px 0px',borderBottom:"1px solid grey"}}>
                <div><img style={{width:"160px",height:"160px",borderRadius:"80px"}}
                src="https://images.unsplash.com/photo-1550927407-50e2bd128b81?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60" alt="Profile Pic"/>
                </div>
                <div>
    <h4>{newProfile.user.name}</h4>
                 <div style={{display:"flex",justifyContent:"space-around",width:"108%"}}>
                     <h5>40 Posts</h5>
                     <h5>40 Followers</h5>
                     <h5>40 Followings</h5>
                 </div>
                 </div>
            </div>
            <div className="gallery">
                 {
                    // userProfile.map((item)=>{
                    //     return (
                    //         <img key={item._id} className="item" src={item.file} alt={item.title}/>
                    //     )
                    // })
                }
                
           
               
             
            </div>
        </div>
    );
}

export default UserProfile;

{newProfile.user.name} giving type undefined

Upvotes: 1

Views: 827

Answers (1)

Drag13
Drag13

Reputation: 5998

newProfile is null when the component start working. You must check before accessing it in the render method:

  {newProfile != null ?
                        <div>
                            <h4>{newProfile.user.name}</h4>
                            <div style={{ display: "flex", justifyContent: "space-around", width: "108%" }}>
                                <h5>40 Posts</h5>
                                <h5>40 Followers</h5>
                                <h5>40 Followings</h5>
                            </div>
                        </div>
                        : 'loading'}

or use the default value in the useState hook

Full version:

import React, { useContext, useEffect, useState } from 'react';
import { useHistory, useParams } from 'react-router-dom'
import { UserContext } from '../../App'
import { Divider } from 'material-ui';

const UserProfile = () => {
    const [newProfile, setProfileData] = useState(null)
    const { state, dispatch } = useContext(UserContext)

    const { userId } = useParams()
    console.log(userId)
    useEffect(() => {
        fetch(`/user/${userId}`, {
            headers: {
                'Authorization': 'Bearer ' + localStorage.getItem('jwt')
            }
        }).then((res) => {
            return res.json()
        }).then((data) => {
            console.log(data)
            setProfileData(data)

        })
    }, [])
    return (
        <div style={{ width: '555px', margin: "0px auto" }}>
            <div style={{ display: "flex", justifyContent: "space-around", margin: '18px 0px', borderBottom: "1px solid grey" }}>
                <div><img style={{ width: "160px", height: "160px", borderRadius: "80px" }}
                    src="https://images.unsplash.com/photo-1550927407-50e2bd128b81?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60" alt="Profile Pic" />
                </div>
                <div>
                    {newProfile != null ?
                        <div>
                            <h4>{newProfile.user.name}</h4>
                            <div style={{ display: "flex", justifyContent: "space-around", width: "108%" }}>
                                <h5>40 Posts</h5>
                                <h5>40 Followers</h5>
                                <h5>40 Followings</h5>
                            </div>
                        </div>
                        : 'loading'}

                </div>
            </div>
            <div className="gallery">
            </div>
        </div>
    );
}

export default UserProfile;

Upvotes: 1

Related Questions