I am trying to make an application that allows the user to select 'Add to cart' within my DetailsComponent.js page. I am currently updating an array within my store named 'cart' with ids that correspond to products within a products array within the store. I have checked the debugger and the product id is correctly being added to the cart array. I am using the following code to show products on my cart page that match the product ids in my cart but my cart is currently showing nothing.
CartComponent.js
import React, { Component } from 'react';
import { FlatList, View, Text, Alert } from 'react-native';
import { ListItem } from 'react-native-elements';
import { connect } from 'react-redux';
import { baseUrl } from '../shared/baseUrl';
import { Loading } from './LoadingComponent';
import { removeCart } from '../redux/ActionCreators';
const mapStateToProps = state => {
return {
products: state.products,
cart: state.cart
}
}
const mapDispatchToProps = dispatch => ({
removeCart: (id) => dispatch(removeCart(id))
});
class CartScreen extends Component {
render() {
const renderMenuItem = ({item, index}) => {
return(
<ListItem
key={index}
bottomDivider
>
<ListItem.Content>
<ListItem.Title>
{item.name}
</ListItem.Title>
<ListItem.Subtitle>
{item.quantity} chargers: ${item.price}
</ListItem.Subtitle>
</ListItem.Content>
</ListItem>
);
}
if (this.props.cart.isLoading) {
return(
<Loading />
)
}
else if (this.props.cart.errMess) {
return(
<Text>{this.props.cart.errMess}</Text>
)
}
else {
return(
<View>
<Text>
Cart
</Text>
<FlatList
data={this.props.products.products.filter(product => this.props.cart.cart.some(el => el === product.id))}
renderItem={renderMenuItem}
keyExtractor={item => item.id.toString()}
/>
</View>
);
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(CartScreen);
I have included my other files for more information.
I have different DropDownPicker values that correspond to the product IDs in my redux store. These items in the store have quantity and price values to be used in the CartComponent.js.
DetailsComponent.js
import React, { Component } from 'react';
import { Text, View, Image, Button, FlatList, StyleSheet, ScrollView} from 'react-native';
import DropDownPicker from 'react-native-dropdown-picker';
import { baseUrl } from '../shared/baseUrl';
import { connect } from 'react-redux';
import { Loading } from './LoadingComponent';
import { postCart } from '../redux/ActionCreators';
const mapStateToProps = state => {
return{
chargers: state.chargers,
utensils: state.utensils,
orders: state.orders,
products: state.products
}
}
const mapDispatchToProps = dispatch => ({
postCart: (id) => dispatch(postCart(id))
})
class DetailsScreen extends Component {
constructor(props) {
super();
this.state = {
itemId: '',
orderAmount: '',
orderPrice: ''
}
}
addToCart(id) {
this.props.postCart(id);
}
render() {
const categoryName = this.props.route.params.categoryName;
const productId = this.props.route.params.menuId;
const item = this.props[categoryName][categoryName][productId];
if (categoryName === "chargers") {
if (productId === 0) {
var amounts = [
{label: '50', value: '1'},
{label: '100', value: '2'},
{label: '150', value: '3'},
{label: '200', value: '4'},
{label: '250', value: '5'},
{label: '300', value: '6'},
{label: '350', value: '7'},
{label: '400', value: '8'},
{label: '450', value: '9'},
{label: '500', value: '10'},
{label: '550', value: '11'},
{label: '600', value: '12'},
];
}
else if (productId === 1) {
var amounts = [
{label: '50', value: '14'},
{label: '100', value: '15'},
{label: '150', value: '16'},
{label: '200', value: '17'},
{label: '250', value: '18'},
{label: '300', value: '19'},
{label: '350', value: '20'},
{label: '400', value: '21'},
{label: '450', value: '22'},
{label: '500', value: '23'},
{label: '550', value: '24'},
{label: '600', value: '25'},
];
}
else if (productId === 2) {
var amounts = [
{label: '50', value: '27'},
{label: '100', value: '28'},
{label: '150', value: '29'},
{label: '200', value: '30'},
{label: '250', value: '31'},
{label: '300', value: '32'},
{label: '350', value: '33'},
{label: '400', value: '34'},
{label: '450', value: '35'},
{label: '500', value: '36'},
{label: '550', value: '37'},
{label: '600', value: '38'},
];
}
}
else if (categoryName === "utensils") {
if (productId === 0) {
var amounts = [
{label: '1', value: '40'},
{label: '2', value: '41'},
{label: '3', value: '42'},
{label: '4', value: '43'},
{label: '5', value: '44'},
];
}
else if (productId === 1) {
var amounts = [
{label: '1', value: '46'},
{label: '2', value: '47'},
{label: '3', value: '48'},
{label: '4', value: '49'},
{label: '5', value: '50'},
];
}
}
if (this.props[categoryName].isLoading) {
return(
<Loading />
)
}
else if (this.props[categoryName].errMess) {
return(
<Text>
{this.props[categoryName][categoryName].errMess}
</Text>
)
}
else {
return(
<ScrollView>
<Text style={styles.title}>
{item.name}
</Text>
<Text>
{item.category}
</Text>
<View style={{flex: 1, flexDirection: 'row'}}>
<Image
style={styles.image}
source={{uri: baseUrl + item.image}}
/>
<DropDownPicker
items={amounts}
defaultNull
placeholder="Select amount"
containerStyle={{height: 40, width: 100}}
itemStyle={{
justifyContent: 'flex-start'
}}
onChangeItem={item => this.setState({
itemId: this.props.products.products[item.value].id,
orderAmount: this.props.products.products[item.value].quantity,
orderPrice: this.props.products.products[item.value].price
})}
/>
</View>
<Text>
{item.description}
</Text>
<Text>
Your order is {this.state.orderAmount} {this.props[categoryName][categoryName][productId].name} chargers for ${this.state.orderPrice}
</Text>
<Button
title='Add to Cart'
color="#f194ff"
onPress={() => this.addToCart(this.state.itemId)}
/>
</ScrollView>
)
}
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
image: {
resizeMode: "contain",
height: 200,
width: 200
},
title: {
fontSize: 32,
},
});
export default connect(mapStateToProps, mapDispatchToProps)(DetailsScreen);
The following code samples are my redux files. I have simplified them with only the cart information for readability.
ActionCreators.js
export const fetchCart = () => (dispatch) => {
dispatch(cartLoading());
return fetch(baseUrl + 'cart')
.then(response => {
if (response.ok) {
return response;
} else {
var error = new Error('Error ' + response.status + ': ' + response.statusText);
error.response = response;
throw error;
}
},
error => {
var errmess = new Error(error.message);
throw errmess;
})
.then(response => response.json())
.then(cart => dispatch(addCart(cart)))
.catch(error => dispatch(cartFailed(error.message)));
};
export const cartLoading = () => ({
type: ActionTypes.CART_LOADING
});
export const cartFailed = (errmess) => ({
type: ActionTypes.CART_FAILED,
payload: errmess
});
export const postCart = (id) => (dispatch) => {
const newCart = {
id: id
};
setTimeout(() => {
dispatch(addToCart(newCart));
}, 2000);
};
export const addToCart = (cart) => ({
type: ActionTypes.ADD_TO_CART,
payload: cart
});
export const addCart = (id) => ({
type: ActionTypes.ADD_CART,
payload: id
});
export const removeCart = (id) => ({
type: ActionTypes.REMOVE_CART,
payload: id
});
ActionTypes.js
export const POST_CART = 'POST_CART';
export const ADD_TO_CART = 'ADD_TO_CART';
export const ADD_CART = 'ADD_CART';
export const REMOVE_CART = 'REMOVE_CART';
export const CART_LOADING = 'CART_LOADING';
export const CART_FAILED = 'CART_FAILED';
cart.js
import * as ActionTypes from './ActionTypes';
export const cart = (
state = {
isLoading: true,
errMess: null,
cart:[]
},
action) => {
switch (action.type) {
case ActionTypes.ADD_CART:
return {...state, isLoading: false, errMess: null, cart: action.payload};
case ActionTypes.CART_LOADING:
return {...state, isLoading: true, errMess: null, cart: []};
case ActionTypes.CART_FAILED:
return {...state, isLoading: false, errMess: action.payload};
case ActionTypes.ADD_TO_CART:
var newCart = action.payload;
return {...state, cart: state.cart.concat(newCart) };
default:
return state;
}
};
The following is my db.json file. I have input one item into the cart array for testing but it also does not show up in the cart. Have also simplified this file to only show a few products for readability.
"products": [
{
"id": 0,
"name": "Ezywhip Pro",
"category": "chargers",
"label": "",
"featured": false,
"description": "Ezywhip Pro Cream Chargers, Made by MOSA",
"image": "images/ezywhip.png",
"quantity": 0,
"price": 0
},
{
"id": 1,
"name": "Ezywhip Pro",
"category": "ezy",
"label": "",
"featured": false,
"description": "Ezywhip Pro Cream Chargers, Made by MOSA",
"image": "images/ezywhip.png",
"quantity": 50,
"price": 40
},
{
"id": 2,
"name": "Ezywhip Pro",
"category": "ezy",
"label": "",
"featured": false,
"description": "Ezywhip Pro Cream Chargers, Made by MOSA",
"image": "images/ezywhip.png",
"quantity": 100,
"price": 70
},
{
"id": 3,
"name": "Ezywhip Pro",
"category": "ezy",
"label": "",
"featured": false,
"description": "Ezywhip Pro Cream Chargers, Made by MOSA",
"image": "images/ezywhip.png",
"quantity": 150,
"price": 110
}
],
"cart": [
{
"id": 1
}
]
}
If anyone could explain what I'm doing wrong it would be greatly appreciated.