1

I am new to react. Now I am Facing a problem. My app is running well(a simple ecommerce).When I am entering a shipping address, it is running fine. But the problem is when i log out from the account and re login again in shipping page then it shows me an error like this,

TypeError: Cannot read property 'address' of null

I am using redux.So when I delete the existing address from browsers Localstorage it runs well.Error Showing

ShippingScreen.js

import React,{useState,useEffect} from 'react'
import { Form,Button } from 'react-bootstrap'
import { useDispatch, useSelector } from 'react-redux'
import FormContainer from '../components/FormContainer'
import { saveShippingAddress } from '../actions/cartActions'
import CheckoutSteps from '../components/CheckoutSteps'

function ShippingScreen({history}) {
    
    const cart = useSelector(state => state.cart)
    const { shippingAddress } = cart
    
    const dispatch = useDispatch()
    
    const [address, setAddress] = useState(shippingAddress.address)
    const [phone, setPhone] = useState(shippingAddress.phone)
    const [city, setCity] = useState(shippingAddress.city)
    const [postalCode, setPostalCode] = useState(shippingAddress.postalCode)
    const [country, setCountry] = useState(shippingAddress.country)
    
    const submitHandler = (e) =>{
        e.preventDefault()
        dispatch(saveShippingAddress({ address,phone,city,postalCode,country }))
        history.push('/payment')
    }
    
    return (
        <FormContainer>
            <CheckoutSteps step1 step2 />
            <h1>Shipping Information</h1>
            <Form onSubmit={submitHandler}>
            
            <Form.Group controlId='address'>
                    <Form.Label>Address</Form.Label> 
                    <Form.Control
                        required
                        type='text'
                        placeholder='Enter Address'
                        value={address ? address : ''}
                        onChange={(e)=> setAddress(e.target.value)}>                    
                    </Form.Control>
                </Form.Group>
                
                <Form.Group controlId='phone'>
                    <Form.Label>Phone Number</Form.Label> 
                    <Form.Control
                        required
                        type='number'
                        placeholder='Enter Phone Number'
                        value={phone ? phone : ''}
                        onChange={(e)=> setPhone(e.target.value)}>                    
                    </Form.Control>
                </Form.Group>
                
                <Form.Group controlId='city'>
                    <Form.Label>City</Form.Label> 
                    <Form.Control
                        required
                        type='text'
                        placeholder='Enter City'
                        value={city ? city : ''}
                        onChange={(e)=> setCity(e.target.value)}>                    
                    </Form.Control>
                </Form.Group>
                
                <Form.Group controlId='postalCode'>
                    <Form.Label>Post Code</Form.Label> 
                    <Form.Control
                        required
                        type='number'
                        placeholder='Enter Post Code'
                        value={postalCode ? postalCode : ''}
                        onChange={(e)=> setPostalCode(e.target.value)}>                    
                    </Form.Control>
                </Form.Group>
                
                <Form.Group controlId='country'>
                    <Form.Label>Country</Form.Label> 
                    <Form.Control
                        required
                        type='text'
                        placeholder='Enter Country'
                        value={country ? country : ''}
                        onChange={(e)=> setCountry(e.target.value)}>                    
                    </Form.Control>
                </Form.Group>
                
                <Button type='submit' variant='primary'>
                    Coninue
                </Button>
            
            </Form>
        </FormContainer>
    )
}

export default ShippingScreen

cartReducer.js

import { CART_ADD_ITEM, 
         CART_REMOVE_ITEM,
         CART_SAVE_SHIPPING_ADDRESS,
        
         CART_SAVE_PAYMENT_METHOD
         } from '../constants/cartConstants'

export const cartReducer = (state={ cartItems:[], shippingAddress: {} },action) =>{
    
    switch (action.type){
        case CART_ADD_ITEM:
            const item=action.payload
            const existItem=state.cartItems.find(x=>x.product===item.product)
            
            if(existItem){
                return{
                    ...state,
                    cartItems: state.cartItems.map(x=>
                                                   x.product === existItem.product ? item : x
                                                )
                }
            }else{
                return{
                    ...state,
                    cartItems:[...state.cartItems, item]
                }
            }
            
        case CART_REMOVE_ITEM:
            return{
                ...state,
                cartItems:state.cartItems.filter(x => x.product !== action.payload)
            }
            
        case CART_SAVE_SHIPPING_ADDRESS:
            return{
                ...state,
                shippingAddress: action.payload
            }
            
        case CART_SAVE_PAYMENT_METHOD:
            return{
                ...state,
                paymentMethod: action.payload
            }
            
        default:
            return state
    }
    
}

cartAction.js

import axios from 'axios'
import { CART_ADD_ITEM, 
         CART_REMOVE_ITEM,
         CART_SAVE_SHIPPING_ADDRESS,
         
         CART_SAVE_PAYMENT_METHOD,
          } from '../constants/cartConstants'

export const addToCart = (id, qty) => async (dispatch, getState)=>{
    const {data} =await axios.get(`http://127.0.0.1:8000/api/products/${id}`)
    
    dispatch({
        type:CART_ADD_ITEM,
        payload:{
            product: data._id,
            name: data.name,
            image: data.image,
            price: data.price,
            countInStock: data.countInStock,
            qty
        }
    })
    
    localStorage.setItem('cartItem' , JSON.stringify(getState().cart.cartItems))
}


export const removeFromCart = (id)=>(dispatch, getState) => {
    dispatch({
        type:CART_REMOVE_ITEM,
        payload:id,
    })
    
    localStorage.setItem('cartItem' , JSON.stringify(getState().cart.cartItems))
}

export const saveShippingAddress = (data)=>(dispatch) => {
    dispatch({
        type:CART_SAVE_SHIPPING_ADDRESS,
        payload:data,
    })
    
    localStorage.setItem('shippingAddress' , JSON.stringify(data))
}

export const savePaymentMethod = (data)=>(dispatch) => {
    dispatch({
        type:CART_SAVE_PAYMENT_METHOD,
        payload:data,
    })
    
    localStorage.setItem('paymentMethod' , JSON.stringify(data))
}

store.js

import { createStore, combineReducers, applyMiddleware } from 'redux'
import thunk from 'redux-thunk';
import { composeWithDevTools } from 'redux-devtools-extension';
import { productListReducers,productDetailsReducers } from './reducers/productReducers';
import { cartReducer } from './reducers/cartReducers'
import { userLoginReducer, userRegisterReducer, userDetailsReducer, userUpdateProfileReducer } from './reducers/userReducers'
import { orderCreateReducer } from './reducers/orderReducers'
const reducer = combineReducers({
    productList: productListReducers,
    productDetails: productDetailsReducers,
    cart: cartReducer,
    userLogin: userLoginReducer,
    userRegister: userRegisterReducer,
    userDetails:userDetailsReducer,
    userUpdateProfile:userUpdateProfileReducer,
    orderCreate:orderCreateReducer,
    
})

const cartItemsFromStorage = localStorage.getItem('cartItems') ? 
    JSON.parse(localStorage.getItem('cartItems')) : []
    
const userInfoFromStorage = localStorage.getItem('userInfo') ? 
    JSON.parse(localStorage.getItem('userInfo')) : null
    
const shippingAddressFromStorage = localStorage.getItem('shippingAddress') ? 
    JSON.parse(localStorage.getItem('sgippingAddress')) : {}

const intitialState = {
    cart:{ 
          cartItems: cartItemsFromStorage,
          shippingAddress: shippingAddressFromStorage,
        },
    userLogin:{userInfo: userInfoFromStorage},
}

const middleware = [thunk]

const store= createStore(reducer,intitialState, 
                         composeWithDevTools(applyMiddleware(...middleware)))

export default store

2 Answers 2

2

There is a typo error on store.js file when you try to get shippingAddress from local storage. You wrote sgippingAddress but should be shippingAddress with the h.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. I have Missed it. Now Its running well!
Happy to ear that =)
2

You have a typo in your store.js ;)

const shippingAddressFromStorage = localStorage.getItem('shippingAddress') ? 
    JSON.parse(localStorage.getItem('->sg<-ippingAddress')) : {}

You might consider using redux-persist, a nice library to persist your redux state to localStorage, indexDB etc.

2 Comments

Basically on the same time. What a timing... =)
Thanks. I have Missed it. Now Its running well! And thanks for the suggestion also!

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.