TypeError: Cannot read properties of null (reading 'attributes') โ€” issue with username?

Hi there! For my hackathon project, I am using ReactJS and have various path routes in my app. For example: app.com/listings and app.com/help

When I click on the navbar buttons that are NavLinks to switch to the page components, there are no issues. However, when I do a hard refresh on specifically my app.com/profile page, I get this error.

I think it has to do with calling the username, but does anyone know what might be causing this? It doesnโ€™t seem to like my useState hook for calling the username. But I am not sure b/c I am using it similarly on another page. Would anyone be able to help me? Iโ€™ve included the error message and my full profile page component code below!

Error Message

TypeError: Cannot read properties of null (reading 'attributes')
ProfileSection
src/components/Profile/index.js:53
  50 | const { logout, isAuthenticating } = useMoralis();
  51 | const { isAuthenticated, user, setUserData, userError, isUserUpdating } = useMoralis();
  52 | 
> 53 | const [username, setUsername] = useState(user.attributes.username);
     | ^  54 | const [email, setEmail] = useState(user.attributes.email);
  55 | const [password, setPassword] = useState('');
  56 | 

Profile Page Code

Iโ€™ve included my full code here:

import React, { useState } from 'react';
import { Redirect, useLocation } from "react-router-dom";

import { ErrorBox } from '../Error';


import { ProfileContainer, ProfileBackground, ProfileInnerCon, FormButtonSignOut, HeroH1, HeroH1Gradient, HeroP, FormLabel, FormInput, FormButton } from './ProfileElements';

import Avatar from '@mui/material/Avatar';
import Badge from '@mui/material/Badge';
import { styled } from '@mui/material/styles';

import { useMoralis } from "react-moralis";

const StyledBadge = styled(Badge)(({ theme }) => ({
    '& .MuiBadge-badge': {
      backgroundColor: '#44b700',
      color: '#44b700',
      boxShadow: `0 0 0 10px #44b700`,
      '&::after': {
        position: 'absolute',
        top: -9,
        left: -9,
        bottom: 0,
        width: '230%',
        height: '230%',
        borderRadius: '50%',
        animation: 'ripple 1.6s infinite ease-in-out',
        border: '4px solid currentColor',
        content: '""',
      },
    },
    '@keyframes ripple': {
      '0%': {
        transform: 'scale(.8)',
        opacity: 1,
      },
      '100%': {
        transform: 'scale(2.4)',
        opacity: 0,
      },
    },
  }));


const ProfileSection = () => {
    const { logout, isAuthenticating } = useMoralis();
    const { isAuthenticated, user, setUserData, userError, isUserUpdating } = useMoralis();

    const [username, setUsername] = useState(user.attributes.username);
    const [email, setEmail] = useState(user.attributes.email);
    const [password, setPassword] = useState('');

    const {location} = useLocation();

    const handleSave = () => {
        setUserData({
            username,
            email,
            password: password === "" ? undefined : password
        })
    }

    if (isAuthenticated) {
    return (
        <ProfileContainer id="home">
            <ProfileBackground>
                <ProfileInnerCon>
                    <center>
                    <StyledBadge
                        overlap="circular"
                        anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
                        variant="dot"
                    >
                    <Avatar
                        sx={{ 
                            bgcolor: "#43A1FF",
                            width: "80px",
                            height: "80px",
                            marginTop: "30px",
                            fontSize: "2.25rem",
                        
                        }}
                        alt="HelpMeDev"
                        src="/broken-image.jpg"
                        name={user.attributes.username}
                        >
                            {username.charAt(0)}
                    </Avatar>
                    </StyledBadge>
                    </center>
                    <HeroH1>Welcome Back,</HeroH1>
                    <HeroH1Gradient className="H1Gradient">{user.attributes.username}</HeroH1Gradient> 
            
            <br></br>
            <br></br>
            <center>
            <HeroP>Update your profile here:</HeroP>
            </center>
            <center>
            <FormLabel htmlFor='for'>Username:</FormLabel>
            <FormInput 
                value={username}
                onChange={(event) => setUsername(event.currentTarget.value)}
                />
            </center>
            
            <center>
            <FormLabel htmlFor='for'>Email:</FormLabel>
            <FormInput 
                value={email}
                onChange={(event) => setEmail(event.currentTarget.value)}
                />
            </center>

            <center>
            <FormLabel htmlFor='for'>Password:</FormLabel>
            <FormInput 
                value={password}
                onChange={(event) => setPassword(event.currentTarget.value)}
                />
            </center>
            
            <center>
            <FormButton 
                type='submit'
                onClick={handleSave}
                isLoading={isUserUpdating}
                >
                    Save Profile Changes
            </FormButton>
            {userError && <ErrorBox title="User change has failed" 
            message={userError.message} />}
           
            <br></br>
            <br></br>
            <br></br>
            <br></br>
            <br></br>
            <FormButtonSignOut 
            type='submit'
            onClick={() => logout()}
            disabled={isAuthenticating}
            >
            Sign Out
            </FormButtonSignOut>
            </center>

            </ProfileInnerCon>
                
            </ProfileBackground> 
        </ProfileContainer>
    )}
    
    if (!isAuthenticated) {
    return (
        <Redirect
        to={{
            pathname: "/",
            state: { from: location }
        }}
        />
    )}
}

export default ProfileSection

1 Like

Hi @InterstellarX

The user object imports after a delay. It means at first render the user is null and thatโ€™s what you see TypeError: Cannot read properties of null (reading 'attributes').

You need to use something like this:

const [username, setUsername] = useState();
const [email, setEmail] = useState();
const [password, setPassword] = useState();

useEffect(() => {
  if (!user) return null;
  setUsername(user.get("username"))
  setEmail(user.get("email"))
}, [user])

1 Like

Thanks so much @Yomoo!!! Absolute life-saver here. You rock.

1 Like

Happy BUIDLing :man_mechanic:

1 Like