1

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

3
  • The argument you passed to useState is the initial value for newProfile, which is null here. So, in the first render, the value of newProfile is equal to null. You need to check for data and show a loading indicator when newProfile is null. Commented Jul 27, 2020 at 20:19
  • @MoradiDavijani yes now its working fine thank you so much, but i have a doubt that i making the other component also like creator profile there also i am fetching the imgs of creator and there use used useState([]) but i didn't used checking condition there and i am getting data and passing to creator profile correctly without any issue. so now i am confused why we don't used that loading condition there?? Commented Jul 28, 2020 at 2:08
  • Anytime. The problem here is that you are trying to access a property on a null value in the first render, so you should check its value before doing so. Commented Jul 28, 2020 at 22:00

1 Answer 1

1

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;
Sign up to request clarification or add additional context in comments.

2 Comments

yes now its working fine thank you so much, but i have a doubt that i making the other component also like creator profile there also i am fetching the imgs of creator and there use used useState([]) but i didn't used checking condition there and i am getting data and passing to creator profile correctly without any issue. so now i am confused why we don't used that loading condition there??
Until you are not trying to access property of maybe null value you are fine. But it is a good practice to do such checks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.