Hi I was working on a project, and I am on a part where I am adding up the total cost of orders in the order summary page. I have used
`
let totalPrice = Object.keys(cartItem).map((menuKey) => (
totalPrice = cartItem[menuKey].cost))
`
to sum up the cost and display totalPrice
I understand that it might be in String right now, although I am not sure why, because I have passed the param as a number (4.29)
Right now I have 3 items in my cart, all 4.29 for now.
As expected from a string's behavior, it is being displayed as 4.294.294.29.
Problem number 1) parseDouble not working. Problem number 2) I have no idea how to use the toFixed(2) method on my code.
Any Idea on how I can implement the total cost method?
Whole File :
`
import {
View,
StyleSheet,
ScrollView,
Alert,
ActivityIndicator,
TouchableOpacity,
Button,
Text
} from "react-native";
import AsyncStorage from "@react-native-async-storage/async-storage";
import { useFocusEffect } from "@react-navigation/native";
import ItemCard from "../components/ItemCard";
import { useState, useCallback } from "react";
import { Swipeable } from "react-native-gesture-handler";
import { Ionicons } from "@expo/vector-icons";
export default function CartScreen({ navigation }) {
const [loading, setLoading] = useState(true);
const [cartItem, setcartItem] = useState({});
const [prevOpenedRow, setPrevOpenedRow] = useState();
const [selectedMenu, setselectedMenu] = useState({});
const CART_KEY = "@carts_Key";
const saveCart = async (menuObj) => {
try {
const jsonValue = JSON.stringify(menuObj);
await AsyncStorage.setItem(CART_KEY, jsonValue);
} catch (e) {
alert(`${title}: ${e}`);
}
};
const deleteCart = async (menuKey) => {
const newItem = { ...cartItem };
delete newItem[menuKey];
setcartItem(newItem);
await saveCart(newItem);
};
const alertBeforeDelete = (menuKeyToDelete) => {
Alert.alert(
"Remove from Cart",
`Removing "${cartItem[menuKeyToDelete].title}"`,
[
{
text: "Cancel",
},
{
text: "Remove",
onPress: () => deleteCart(menuKeyToDelete),
style: "destructive",
},
]
);
};
const clearCart = async () => {
const emptyCart = {};
setcartItem(emptyCart);
await saveCart(emptyCart);
};
const alertBeforeClear = () => {
Alert.alert(
"Clearing All Items at Cart",
"Clearing Cart Now. Are you sure?",
[
{
text: "Cancel",
},
{
text: "Yes, Clear",
onPress: () => clearCart(),
style: "destructive",
},
]
);
};
console.log(cartItem)
let totalPrice = Object.keys(cartItem).map((menuKey) => (
totalPrice = cartItem[menuKey].cost))
// Swipeable code modified;
const renderRightActions = (progress, dragX, alertBeforeDelete) => {
return (
<View
style={{
margin: 0,
alignContent: "center",
justifyContent: "center",
width: 70,
}}
>
<TouchableOpacity
style={styles.deleteButton}
onPress={alertBeforeDelete}
>
<Ionicons name="trash" size={40} color="#fff" />
</TouchableOpacity>
</View>
);
};
const closeRow = (menuKey) => {
if (prevOpenedRow && prevOpenedRow !== selectedMenu[menuKey]) {
prevOpenedRow.close();
}
setPrevOpenedRow(selectedMenu[menuKey]);
};
useFocusEffect(
useCallback(() => {
const getCart = async () => {
try {
const jsonValue = await AsyncStorage.getItem(CART_KEY);
setcartItem(jsonValue != null ? JSON.parse(jsonValue) : {});
} catch (e) {
alert(`${e}`);
}
};
getCart();
setLoading(false);
return () => {
};
}, [])
);
return loading ? (
<View style={styles.loadingPage}>
<ActivityIndicator size="large" color="#ffffff" />
</View>
) : (
<>
<Text style={styles.titleText}>Your Current Orders:</Text>
<View style={styles.container}>
<ScrollView>
{Object.keys(cartItem).map((menuKey) => (
<TouchableOpacity
key={menuKey}
onPress={() => {
navigation.navigate({
name: "customize",
params: {
text: cartItem[menuKey].text,
image: cartItem[menuKey].image,
cost: cartItem[menuKey].cost,
},
});
}}
>
<Swipeable
renderRightActions={(progress, dragX) => renderRightActions(progress, dragX, () => alertBeforeDelete(menuKey)
)}
ref={(ref) => (selectedMenu[menuKey] = ref)}
onSwipeableOpen={() => closeRow(menuKey)}
rightOpenValue={-100}
>
<ItemCard
text={cartItem[menuKey].text}
image={cartItem[menuKey].image}
cost ={cartItem[menuKey].cost}
/>
</Swipeable>
</TouchableOpacity>
))}
<View style={styles.priceBlock}><Text style = {styles.totalText}>Total Price: ${totalPrice}</Text></View>
<View style={styles.itemTextBlock}>
<TouchableOpacity
style={styles.clearButton}
title="clear"
color="red"
onPress={alertBeforeClear}>
<Text style={styles.buttonText}>Clear All</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.checkoutButton}
onPress={() => {
navigation.navigate('Past Orders');
clearCart();
}}
>
<Text style={styles.buttonText}>Checkout</Text>
</TouchableOpacity>
</View>
</ScrollView>
</View></>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "white",
},
loadingPage: {
flex: 1,
backgroundColor: "white",
justifyContent: "center",
},
deleteButton: {
color: "red",
backgroundColor: "#f5392f",
height: "95%",
borderRadius: 15,
justifyContent: "center",
alignItems: "center",
},
titleText: {
fontSize: 30,
fontWeight: "bold",
color: "black",
resizeMode: "contain",
textAlign: "center"
},
clearButton: {
width: "40%",
borderRadius: 25,
height: 50,
alignItems: "center",
justifyContent: "center",
backgroundColor: "grey",
},
checkoutButton: {
width: "40%",
borderRadius: 25,
height: 50,
alignItems: "center",
justifyContent: "center",
backgroundColor: "#800000",
},
buttonText: {
color: 'white',
fontWeight: 'bold'
},
itemTextBlock: {
alignItems: "center",
flex: 1,
flexDirection: "row",
justifyContent: "space-evenly",
marginBottom: 100,
},
priceBlock: {
alignItems: "center",
marginBottom: 10,
},
totalText: {
textAlign: "center",
fontSize:24,
fontWeight: "bold",
},
});
`
I have tried parseDouble and toFixed(2)
CodePudding user response:
To be honest I thought
let totalPrice = Object.keys(cartItem).map((menuKey) => (
totalPrice = cartItem[menuKey].cost))
would throw an error.
What I think is the best way to go about this is to use reduce to get your sum:
const initialValue = 0;
const totalPrice = Object.keys(cartItem).reduce((prevValue,currentVal)=>{
let num = parseFloat(cartItem[currentVal].cost);
// if number cant be parsed do nothing
if(isNaN(num))
return prevValue
return prevValue num;
},initialValue);
If you want to use map:
let totalPrice = 0;
Object.keys(cartItem).map((menuKey) => {
let num = parseFloat(cartItem[menuKey].cost)
if(isNaN(num))
return
totalPrice = num
})