Search code examples
reactjsreduxredux-toolkit

Cannot read properties of undefined (reading 'user') TypeError: Cannot read properties of undefined (reading 'user')


I am trying to register user and I am getting error as user is undefined I am getting error in reducer whenever i click register the user then this error window appear and then the user is registering successfully.

Error log

Uncaught runtime errors:

ERROR
`Cannot read properties of undefined (reading 'user')
TypeError: Cannot read properties of undefined (reading 'user')
    at http://localhost:3000/static/js/bundle.js:1493:28
    at http://localhost:3000/static/js/bundle.js:3065:20
    at produce (http://localhost:3000/static/js/bundle.js:60637:17)
    at http://localhost:3000/static/js/bundle.js:3064:67
    at Array.reduce (<anonymous>)
    at reducer (http://localhost:3000/static/js/bundle.js:3045:25)
    at reducer (http://localhost:3000/static/js/bundle.js:3146:14)
    at combination (http://localhost:3000/static/js/bundle.js:50634:29)
    at hu (<anonymous>:3:1043)
    at yu (<anonymous>:3:1331)

Error in console

authSlice.js:36  Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'user')
    at authSlice.js:36:1
    at createReducer.ts:294:1
    at produce (immerClass.ts:94:1)
    at createReducer.ts:293:1
    at Array.reduce (<anonymous>)
    at reducer (createReducer.ts:260:1)
    at reducer (createSlice.ts:372:1)
    at combination (redux.js:560:1)
    at hu (<anonymous>:3:1043)
    at yu (<anonymous>:3:1331)

authSlice.js

import {createSlice} from '@reduxjs/toolkit'
import { getcurrentUser, userLogin, userRegister } from './authActions';
const token= localStorage.getItem('token') ? localStorage.getItem('token'):null
const initialState={
    loading:false,
    user:null,
    token,
    error:null
}
const authSlice = createSlice({
    name:'auth',
    initialState:initialState,
    reducers:{},
    extraReducers: (builder)=>{
        //login user
        builder.addCase(userLogin.pending, (state)=>{
            state.loading= true;
            state.error= null
        })
        builder.addCase(userLogin.fulfilled,(state, {payload})=>{
            state.loading=false;
            state.user=payload.user;
            state.token= payload.token;
        })
        builder.addCase(userLogin.rejected,(state,{payload})=>{
            state.loading=false;
            state.error=payload;
        });
        //register user
        builder.addCase(userRegister.pending, (state)=>{
            state.loading= true;
            state.error= null
        })
        builder.addCase(userRegister.fulfilled,(state, {payload})=>{
            state.loading=false;
            state.user=payload.user;
         
        })
        builder.addCase(userRegister.rejected,(state,{payload})=>{
            state.loading=false;
            state.error=payload;
        });
        //current user
        builder.addCase(getcurrentUser.pending, (state)=>{
            state.loading= true;
            state.error= null
        })
        builder.addCase(getcurrentUser.fulfilled,(state, {payload})=>{
            state.loading=false;
            state.user=payload.user;
         
        })
        builder.addCase(getcurrentUser.rejected,(state,{payload})=>{
            state.loading=false;
            state.error=payload;
        });
    }
});
export default authSlice;

authcontroller.js

const userModel = require("../models/userModel");
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const registerController =async(req,res)=>{
    try {
        const exisitingUser= await userModel.findOne({email:req.body.email})
        if(exisitingUser){
            return res.status(200).send({
                success:false,
                message:'User Already exists'
            })
        }
        const salt= await bcrypt.genSalt(10)
        const hashedPassword= await bcrypt.hash(req.body.password,salt)
        req.body.password=hashedPassword
        //res data
        const user= new userModel(req.body)
        await user.save()
        return res.status(201).send({
            success:true,
            message:'User Registered successfully',
            user,
        })

    } catch (error) {
        console.log(error);
        res.status(500).send({
            success:false,
            message:'Error in Register API',
            error
        })
    }
}
const logincontroller=async(req,res)=>{
    try {
        const user=await userModel.findOne({email:req.body.email})
        if(!user){
            return res.status(404).send({
                success:false,
                message:'User Not Found'
            })
        }
        //check role
        if(user.role !== req.body.role){
            return res.status(500).send({
                success:false,
                message:'role does not match'
            })
        }
        const comparePassword= await bcrypt.compare(req.body.password,user.password)
        if(!comparePassword){
            return res.status(500).send({
                success:false,
                message:'Invalid Credentials' 
            })
        }
        const token=jwt.sign({userId:user._id},process.env.JWT_SECRET,{expiresIn:'1d',})
        return res.status(200).send({
            success:true,
            message:'Login Successfully',
            token,
            user,
        })
    } catch (error) {
        console.log(error);
        res.status(500).send({
            success:false,
            message:'Error in Login API',
            error
        })
    }
}

module.exports={registerController, logincontroller,currentUserController};

authActions.js

import {createAsyncThunk} from '@reduxjs/toolkit'
import API from '../../../services/API';
import { toast } from 'react-toastify';

export const userLogin = createAsyncThunk(
    'auth/login',
     async({role,email,password},{rejectWithValue})=>{
        try {
            const {data}= await API.post('/auth/login',{role,email,password})
            //store token
            if(data.success){
                localStorage.setItem('token',data.token);
                toast.success(data.message)
                window.location.replace('/');

            }
            
            return data;
        } catch (error) {
            if(error.response && error.response.data.message){
                return rejectWithValue(error.response.data.message);
            }else{
                return rejectWithValue(error.message)
            }
        }
     }       
);

export const userRegister= createAsyncThunk(
    'auth/register',
    async ({name,role,email,password,organisationName,hospitalName,address,phone},{rejectWithValue})=>{
        try {
            const {data}= await API.post('/auth/register',{name,role,email,password,organisationName,hospitalName,address,phone})
            if(data?.success){
                toast.success('user register successfully');
                window.location.replace('/login');
            }
        } catch (error) {
            console.log(error);
            if(error.response && error.response.data.message){
                return rejectWithValue(error.response.data.message);
            }else{
                return rejectWithValue(error.message)
            }
        }
    }
)

The user is able to register but this error is ocuured .I am expecting The error should be resolve


Solution

  • You used rejectWithValue for api request reject but you didn't use fulfillWithValue for api request fulfilled

    export const userLogin = createAsyncThunk(
        'auth/login',
         async({role,email,password},{rejectWithValue,fulfillWithValue})=>{
            try {
                const {data}= await API.post('/auth/login',{role,email,password})
                //store token
                if(data.success){
                    localStorage.setItem('token',data.token);
                    toast.success(data.message)
                    window.location.replace('/');
    
                }
                
                return fulfillWithValue(data);
            } catch (error) {
                if(error.response && error.response.data.message){
                    return rejectWithValue(error.response.data.message);
                }else{
                    return rejectWithValue(error.message)
                }
            }
         }       
    );
    
    export const userRegister= createAsyncThunk(
        'auth/register',
        async ({name,role,email,password,organisationName,hospitalName,address,phone},{rejectWithValue})=>{
            try {
                const {data}= await API.post('/auth/register',{name,role,email,password,organisationName,hospitalName,address,phone})
                if(data?.success){
                    toast.success('user register successfully');
                    window.location.replace('/login');
                }
                return fulfillWithValue(data)
            } catch (error) {
                console.log(error);
                if(error.response && error.response.data.message){
                    return rejectWithValue(error.response.data.message);
                }else{
                    return rejectWithValue(error.message)
                }
            }
        }
    )