Reputation: 1401
I have listed out some products in product list page. I am not able to add product in my cart. It is showing error in my reducer code. Here is my code.
action
export const addToCart = id => ({
type: ADD_TO_CART,
id
});
reducer code
const initialState = {
products: [
{
id: 1,
title: "Dell Inspiron 3581",
discount: 10,
price: 110,
img: Image1,
},
{
id: 2,
title: "Dell Vostro 3362",
discount: 10,
price: 80,
img: Image2,
},
{ id: 3, title: "Acer TravelMate", discount: 0, price: 120, img: Image3 },
{
id: 4,
title: "Lenovo ideapad core",
discount: 15,
price: 260,
img: Image4,
},
{ id: 5, title: "Lenovo V145", discount: 0, price: 160, img: Image5 },
{
id: 6,
title: "Asus Zephyrus G14",
discount: 5,
price: 90,
img: Image6,
},
],
filteredProducts: [],
cartItems: [],
total: 0,
cartCount: 0,
};
export default function productReducer(state = initialState, action){
switch(action.type){
case ADD_TO_CART:
const { cartItems, products, cartCount,total } = state;
let productToAdd = cartItems.find(item=>item.id===action.id);
let count;
if (!productToAdd) {
productToAdd = products.find(obj => obj.id === action.id);
count = 1;
} else {
count = productToAdd.count + 1;
}
const pid = productToAdd.id;
const newCart = { ...state.cartItems, [pid]: { ...productToAdd, count } };
const newcount = cartCount + 1;
const newTotal = total+productToAdd.price
return { ...state, cartItems: newCart, cartCount: newcount,total:newTotal};
default:
return state;
}
}
here i am doing the count of added items if that product is already exist in cart then increase quantity of that product. But i am getting type error because of null reference.
TypeError: Unable to get property 'id' of undefined or null reference ->(const pid = productToAdd.id)
Here is my productcomponent page :
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import {addToCart} from '../../action/cartAction';
import {Button} from 'react-bootstrap';
class ProductComponent extends Component{
constructor(props){
super(props);
this.state ={
radioSearch : '',
filteredData: this.props.products
}
}
handleClick = (id)=>{
this.props.addToCart(id);
}
/** some other handler **/
render(){
let itemList = this.state.filteredData.map(item=>{
return(
<div className="card" key={item.id}>
<div className="card-image">
<img src={item.img} alt={item.title}/>
<span className="card-title">{item.title}</span>
</div>
<div className="card-content">
<p><b>Discount: {item.discount}%</b></p>
<p><b>Price: {item.price}$</b></p> <Button variant="dark" onClick={()=>{this.handleClick(item.id)}}>ADD TO CART</Button>
</div>
</div>
)
})
return(
<div className="container">
/** some other code **/
<div className="box">
{itemList}
</div>
</div>
)
}
}
const mapStateToProps = (state)=>{
return {
products: state.productReducer.products
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({
addToCart
}, dispatch);
export default connect(mapStateToProps,mapDispatchToProps)(ProductComponent)
here is my cartcomponent
import React, { Component } from 'react';
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import {removeFromCart} from '../../action/cartAction';
class cartComponent extends Component {
handleRemove(id){
this.props.removeFromCart(id);
}
render() {
console.log(this.props.cartItems.length);
let cartProducts = this.props.cartItems.length ?
(
this.props.cart.map(item=>{
return(
<li className="collection-item avatar" key={item.id}>
<div className="item-img">
<img src={item.img} alt={item.img} className=""/>
</div>
<div className="item-desc">
<span className="title">{item.title}</span>
<p>{item.desc}</p>
<p><b>Price: {item.price}$</b></p>
<p>
<b>Quantity: {item.quantity}</b>
</p>
<button className="waves-effect waves-light btn pink remove" onClick={()=>{this.handleRemove(item.id)}}>Remove</button>
</div>
</li>
)
})
):
(
<p>Your cart is empty</p>
)
return(
<div className="container">
<div className="cart">
<h5>You have ordered:</h5>
<ul className="collection">
{cartProducts}
</ul>
</div>
</div>
)
}
}
function mapStateToProps(state) {
return {
cartItems : state.productReducer.cartItems
}
}
function mapActionsToProps(dispatch) {
return bindActionCreators({
removeFromCart
}, dispatch);
}
export default connect(mapStateToProps,mapActionsToProps)(cartComponent);
i have tried many things but it is not adding product to cart. what are the changes needed to make it work?
Here is my source code : source code
Upvotes: 0
Views: 1156
Reputation: 483
In productReducer file you should push the item into state.cartItems
if (!productToAdd) {
productToAdd = products.find(obj => obj.id === action.id);
count = 1;
ADD row-> state.cartItems.push(productToAdd);
}
In this approach, if you don't enter a specified quantity of the product, it will be automatically placed to the cart as one item.
Upvotes: 0
Reputation: 14385
It looks like the way you map the action to props does not match the actual usage of the function.
You map it like this:
addToCart: (id)=>{dispatch(addToCart(id))}
The action just passes its parameter as payload
meaning payload
is equal to id
:
export const addToCart= payload =>({
type: ADD_TO_CART,
payload
});
But you expect the payload to be an object like this:
const { id } = action.payload;
You need to make them match. Either pass the action an object:
addToCart: (id)=>{dispatch(addToCart({id}))}
Or use the payload as the id:
const id = action.payload;
The result of the code as is, is that id
is undefined, meaning no productToAdd
.
Upvotes: 1