How to Use AsyncStorage in react native expo cli functional component - firebase

I am trying to use Async Storage in react native expo cli to use login credentials even after closing the app. I am using firebase otp authentication as a mode of login. I am struck here to use the previously used phone number and otp. Below is my code.
This is one screen where user will enter mobile number.
import React, {useState, useRef} from 'react'
import { Alert, View } from 'react-native';
import { NativeBaseProvider, Text, Image, Button, Input } from 'native-base';
import { Pressable } from 'react-native';
import { Col, Row, Grid } from "react-native-easy-grid";
import { LinearGradient } from 'expo-linear-gradient';
import styles from '../styles/styles';
import firebase, {phoneAuthProvider} from '../firebase';
import { FirebaseRecaptchaVerifierModal } from 'expo-firebase-recaptcha';
import AsyncStorage from '#react-native-async-storage/async-storage';
const DummyWelcome = ({ navigation }) => {
const [phoneNumber, setPhoneNumber] = useState("");
const [verificationId, setVerificationId] = useState(null);
const recaptchaVerifier = useRef(null);
const sendVerification = async () => {
try {
await AsyncStorage.setItem('phoneNumber', phoneNumber)
}
catch (erorr) {
console.log(error);
}
console.log('Storing phone Number') ;
phoneAuthProvider
.verifyPhoneNumber(phoneNumber, recaptchaVerifier.current)
.then((id) => {
// console.log('verification:',id);
setVerificationId(id);
navigation.navigate("DumOtp", {verificationId: id})
});
};
return (
<NativeBaseProvider>
<FirebaseRecaptchaVerifierModal
ref={recaptchaVerifier}
firebaseConfig={firebase.app().options} />
<Grid >
<LinearGradient
colors={['#64B278', '#03621B']}
style={styles.linearStyle}/>
<Row size={40}
style={styles.containerRow}>
<Image
source={{uri: 'https://d2j6dbq0eux0bg.cloudfront.net/images/30049435/1646525107.jpg'}}
alt="Subhiksha Logo"
width= {150}
height={150}/>
</Row>
<Row size={5}
style={styles.textStyle}>
<Text
style={styles.welcomeText}>Welcome</Text>
</Row>
<Row size={5}
style={styles.textStyle}>
<View>
<Text style={styles.phoneText}>Enter your phone number to contine</Text>
</View>
</Row>
<Row size={10}
style={styles.justifyCenter}>
<Input
style={styles.inputText}
placeholder="Enter your phone Number"
placeholderTextColor= "white"
onChangeText={text => setPhoneNumber(text)}
maxLength={13}
keyboardType='phone-pad'/>
</Row>
<Row size={20}
style={styles.justifyCenter}>
<Pressable
style={styles.pressableStyle}
onPress={sendVerification}>
{/* onPress = {() => */}
{/* text.length < 10 ? Alert.alert("Invalid Submission", "Please Enter 10 digit Mobile Number to continue") : navigation.navigate("DumOtp")}> */}
<Text
style={styles.pressableTextStyle}>Generate OTP</Text>
</Pressable>
</Row>
</Grid>
</NativeBaseProvider>
)
}
export default DummyWelcome
This is another screen where otp will be auto captured.
import React,{ useState, useEffect, useRef } from 'react'
import { NativeBaseProvider, Image, View, Pressable, Text, Button } from 'native-base'
import { Col, Row, Grid } from "react-native-easy-grid";
import { LinearGradient } from 'expo-linear-gradient';
import OTPInputView from '#twotalltotems/react-native-otp-input'
import Clipboard from '#react-native-community/clipboard'
import styles from '../styles/styles';
import AsyncStorage from '#react-native-async-storage/async-storage';
import firebase from '../firebase';
import { FirebaseRecaptchaVerifierModal } from 'expo-firebase-recaptcha';
const DummyOtp = ({ navigation, route }) => {
const [seconds, setSeconds] = useState(60);
const [code, setCode] = useState('');
// const [verificationId, setVerificationId] = useState(null);
const recaptchaVerifier = useRef(null);
const {verificationId} = route.params;
// console.log(code)
useEffect(() => {
if (seconds > 0) {
setTimeout(() => setSeconds(seconds - 1), 1000);
} else {
setSeconds('OTP Expired!');
}
});
const confirmCode = async () => {
try {
const dataa = await AsyncStorage.getItem('phoneNumber');
if(dataa!== null){
const credential = firebase.auth.PhoneAuthProvider.credential(
verificationId,
code
);
firebase
.auth()
.signInWithCredential(credential)
.then((result) => {
// console.log(result);
navigation.navigate("DumQuestion1");
});
}
}
catch (error) {
console.log(error)
}
}
return (
<NativeBaseProvider>
{/* <FirebaseRecaptchaVerifierModal
ref={recaptchaVerifier}
firebaseConfig={firebase.app().options}/> */}
<Grid >
<LinearGradient
colors={['#64B278', '#03621B']}
style={styles.linearStyle}
/>
<Row size={30}
style={styles.justifyCenter}>
<Image
source={{uri: 'https://d2j6dbq0eux0bg.cloudfront.net/images/30049435/1646525107.jpg'}}
alt="Subhiksha Logo"
width= {150}
height={150}
/>
</Row>
<Row size={5}
style={styles.textStyle}>
<Text
style={styles.welcomeText}>Welcome</Text>
</Row>
<Row size={5}
style={styles.textStyle}>
<View>
<Text style={styles.phoneText}>Enter one time password to contine</Text>
</View>
</Row>
<Row size={10}
style={styles.otpRow}>
<OTPInputView
style={styles.otpStyles}
pinCount={6}
autoFocusOnLoad
codeInputFieldStyle={styles.codeInputFieldStyle}
codeInputHighlightStyle={styles.codeInputHighlightStyle}
onChangeText={text => setCode(text)}
onCodeFilled = {(code => {
setCode(code);
})}
/>
</Row>
<Row size={10}
style={styles.centerContainer}>
<Text style={styles.otpTimerText}>{seconds}</Text>
</Row>
<Row size={10}
style={styles.centerContainer}>
<Text underline style={styles.otpNotRecieved}>Didn't receive OTP?</Text>
<Text style={styles.resendText}> Resend</Text>
</Row>
<Row size={15}
style={{alignItems: 'flex-start', justifyContent: 'center', marginTop: 10}}>
<Pressable
style={styles.pressableStyle}
onPress={confirmCode}>
<Text
style={styles.pressableTextStyle}>Authenticate</Text>
</Pressable>
</Row>
{/* <Row size={15}
style={{alignItems: 'flex-start', justifyContent: 'center', marginTop: 10}}>
<Pressable
style={styles.pressableStyle}
onPress={() => console.log(verificationId)}>
<Text
style={styles.pressableTextStyle}>Login</Text>
</Pressable>
</Row> */}
</Grid>
</NativeBaseProvider>
)
}
export default DummyOtp;

Related

How to style diffently item in a flatlist?

Hi everyone i have a problem styling every item present in a flatlist. i find on stackoverflow that you have to use index in the render item but in the render item i have a component that contains all of my items .
What i wanted to reach is this result :
here is my code in the home component:
import React, {useEffect, useState} from 'react';
import {
FlatList,
Pressable,
ScrollView,
StyleSheet,
Text,
View,
} from 'react-native';
import {Audio, Book} from '../types';
import customData from '../books.json';
import BookBox from '../components/BookBox';
import Menu from 'react-native-vector-icons/Entypo';
import Glass from 'react-native-vector-icons/Entypo';
export default function HomeScreen() {
const [books, setBooks] = useState<Book[]>([]);
const [audio, setAudio] = useState<Audio[]>([]);
const [selected, setSelected] = useState(false);
const [selectedAudio, setSelectedAudio] = useState(false);
useEffect(() => {
setBooks(customData);
}, []);
const renderBooks = ({item}: {item: Book}) => <BookBox book={item} />;
return (
<ScrollView nestedScrollEnabled={true} style={styles.scrollContainer}>
<View style={styles.searchContainer}>
<Menu name={'menu'} size={30} color={'black'} />
<Text style={styles.textSearch}>All Books</Text>
<Glass name={'magnifying-glass'} size={30} color={'black'} />
</View>
<View style={styles.AudioOrEbookContainer}>
<Pressable
onPress={() => setSelected(!selected)}
style={{backgroundColor: selected ? 'white' : 'transparent'}}>
<View style={styles.btn}>
<Text>Ebook</Text>
</View>
</Pressable>
<Pressable
style={{backgroundColor: selectedAudio ? 'white' : 'transparent'}}>
<View style={styles.btn}>
<Text>Audiobook</Text>
</View>
</Pressable>
</View>
<View style={styles.container}>
<FlatList
data={books}
keyExtractor={item => item.id?.toString()}
renderItem={renderBooks}
numColumns={2}
/>
</View>
</ScrollView>
);
}
here is my code in BookBox component:
import {Text, Image, StyleSheet, View, TouchableHighlight} from 'react-native';
import React from 'react';
import {Book} from '../types';
import {useNavigation} from '#react-navigation/native';
interface Props {
book: Book;
}
export default function BookBox({book}: Props) {
const {
author,
country,
imageLink,
language,
link,
pages,
title,
year,
overview,
vote,
} = book;
const navigation = useNavigation();
return (
<View style={styles.container}>
{imageLink && (
<TouchableHighlight
onPress={() =>
navigation.navigate('SingleBook', {
title,
year,
pages,
link,
language,
imageLink,
country,
author,
overview,
vote,
})
}>
<Image
style={styles.image}
source={{
uri: `${imageLink}`,
}}
/>
</TouchableHighlight>
)}
{!imageLink && <Text>immagine mancante</Text>}
<View style={styles.wrap}>
<Text style={styles.title}>{title}</Text>
<Text style={styles.title}>{author}</Text>
</View>
</View>
);
}
i'm trying to render items with unique style like in the image above.. can you help me? thank you in avance
So, numColumns of FlatList cannot help you to achieve the behavior you want. This is because masonry are not supported by this property, in other words, numColumns sets the same height for every item at the same line. As a resort to implementing this behavior you can check this lib: https://github.com/hyochan/react-native-masonry-list

Error: [auth/unknown] Cannot create PhoneAuthCredential without either verificationProof, sessionInfo, temporary proof, or enrollment ID

I am trying to make a Login page with Phone Authentication to use React-Native-Firebase sdk and I receive OTP through sms and when I confirm the received OTP ,I got a error that: [Error: [auth/unknown] Cannot create PhoneAuthCredential without either verificationProof, sessionInfo, temporary proof, or enrollment ID.]
I am using-
React:18.0.0
React-Native: 0.69.1
React-Native-Firebase:^15.1.1
My code is-
import React, {useState} from 'react';
import {
View,
Text,
StyleSheet,
Image,
TextInput,
TouchableOpacity,
Alert,
} from 'react-native';
import PhoneInput from 'react-native-phone-number-input';
import auth from '#react-native-firebase/auth';
const Login = () => {
const [PhoneNumber, setPhoneNumber] = useState('');
const [otpInput, setOtpInput] = useState('');
const [confirmData, setConfirmData] = useState('');
const sendOtp = async () => {
try {
const responce = await auth().signInWithPhoneNumber(PhoneNumber);
setConfirmData(responce);
console.log(responce);
Alert.alert('Otp is sent please varify it');
} catch (error) {
console.log(error);
}
}
const submitOtp = async () => {
try {
const responce = await confirmData.confirm(otpInput);
console.log(responce);
Alert.alert('Your Number is verified');
} catch (error) {
console.log(error);
}
}
return (
<View>
<View style={styles.con}>
<Text style={styles.container}>Login Screen</Text>
<Image source={require('../assets/logo.png')} style={styles.image} />
</View>
<View style={styles.inputContainer}>
<Text style={styles.labels}>Phone Number:</Text>
<PhoneInput
style={styles.inputStyle}
defaultValue={PhoneNumber}
defaultCode="DM"
layout="first"
keyboardType="number-pad"
onChangeFormattedText={text => setPhoneNumber(text)}
onChangeText={(value) => setPhoneNumber(value)}
/>
</View>
<View>
<TouchableOpacity
style={styles.buttonStyle}>
<Text style={styles.buttonText}>Verify</Text>
</TouchableOpacity>
</View>
<View style={styles.otpContainer}>
<TextInput
style={styles.otpStyle}
placeholder="Enter OTP"
autoCapitalize="none"
secureTextEntry={true}
onChangeText={(value) => setOtpInput(value)}/>
</View>
<View>
<TouchableOpacity style={styles.continueStyle}>
<Text
style={styles.buttonText}
onPress={() => submitOtp()}>
Continue
</Text>
</TouchableOpacity>
</View>
</View>
);
};
export default Login;

Reason: `object` ("[object Object]") cannot be serialized as JSON. Please only return JSON serializable data types

I am using next.js immutable Js and redux saga.
Error: Error serializing .initialState.ui returned from
getServerSideProps in "/me/profile-setting". Reason: object
("[object Object]") cannot be serialized as JSON. Please only return
JSON serializable data types.
profile-settings:
import React from "react";
import {
Button,
FormControl,
FormControlLabel,
Grid,
InputAdornment,
makeStyles,
Radio,
RadioGroup,
Typography,
Avatar,
TextField,
} from "#material-ui/core";
import { Email } from "#material-ui/icons";
import { manCategory } from "assets/constants";
const useStyles = makeStyles((theme) => ({
root: {
padding: theme.spacing(2),
paddingTop: theme.spacing(3),
},
icon: {
fontSize: theme.spacing(13),
},
radio: {
flexDirection: "row",
},
deactivate: {
color: theme.palette.error.main,
},
large: {
width: theme.spacing(10),
height: theme.spacing(10),
},
}));
export default function ProfileSetting() {
const classes = useStyles();
const [canEditPersonal, setCanEditPersonal] = React.useState(false);
const [canEditEmail, setCanEditEmail] = React.useState(false);
const [canEditNumber, setCanEditNumber] = React.useState(false);
return (
<Container>
<Grid container spacing={2}>
<Grid item xs={12} container>
<Avatar alt="Ameed" src={manCategory} className={classes.large} />
</Grid>
<Grid item xs={12} container>
<Grid item xs={12}>
<Typography variant="h6">
Personal Information
<ToggleButtons
condition={canEditPersonal}
toggler={setCanEditPersonal}
/>
</Typography>
</Grid>
<Grid item xs={12} container spacing={2}>
<CustomTextField
margin="normal"
value={"Ameed"}
disabled={!canEditPersonal}
/>
<CustomTextField
margin="normal"
value={"Faridi"}
disabled={!canEditPersonal}
/>
</Grid>
<Grid item xs={12}>
<FormControl
component="fieldset"
margin="normal"
disabled={!canEditPersonal}
>
<RadioGroup
aria-label="gender"
name="gender1"
className={classes.radio}
value="male"
>
<FormControlLabel
value="male"
control={<Radio color="primary" />}
label="Male"
/>
<FormControlLabel
value="female"
control={<Radio color="primary" />}
label="Female"
/>
</RadioGroup>
</FormControl>
</Grid>
<Grid item xs={12}>
<Typography variant="h6">
Email Address
<ToggleButtons
condition={canEditEmail}
toggler={setCanEditEmail}
/>
</Typography>
</Grid>
<Grid item xs={12}>
<CustomTextField
margin="normal"
value={"faridiameed5#gmail.com"}
disabled={!canEditEmail}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<Email color={canEditEmail ? "primary" : "disabled"} />
</InputAdornment>
),
}}
/>
</Grid>
<Grid item xs={12}>
<Typography variant="h6">
Mobile Number
<ToggleButtons
condition={canEditNumber}
toggler={setCanEditNumber}
/>
</Typography>
</Grid>
<Grid item xs={12}>
<CustomTextField
margin="normal"
value={"8218632822"}
disabled={!canEditNumber}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<Typography>+91 |</Typography>
</InputAdornment>
),
}}
/>
</Grid>
<Grid item xs={12} container justifyContent="space-between">
<Button color="primary" size="small">
change my password
</Button>
<Button className={classes.deactivate} size="small">
Deactivate Account
</Button>
</Grid>
</Grid>
</Grid>
</Container>
);
}
const ToggleButtons = ({ condition, toggler }) => {
return condition ? (
<>
<Button color="primary" size="small" onClick={() => toggler(false)}>
Save
</Button>
<Button color="primary" size="small" onClick={() => toggler(false)}>
Cancel
</Button>
</>
) : (
<Button color="primary" size="small" onClick={() => toggler(true)}>
Edit
</Button>
);
};
const CustomTextField = (props) => {
return <TextField variant="outlined" size="small" {...props} />;
};
const Container = ({ children }) => {
const classes = useStyles();
return <div className={classes.root}>{children}</div>;
};
meReducer
import { fromJS } from "immutable";
import { HYDRATE } from "next-redux-wrapper";
import * as Actions from "modules/me/constants";
const initialState = fromJS({
currentPage: "",
});
export default function meReducer(state = initialState, { type, payload }) {
switch (type) {
case Actions.SWITCH_ME_PAGE:
return state.set("currentPage", payload);
case HYDRATE:
console.log({ payload });
return state.set("currentPage", payload.me.currentPage);
default:
return state;
}
}
uiReducer:
import { fromJS } from "immutable";
import * as Actions from "modules/ui/constants";
import { HYDRATE } from "next-redux-wrapper";
const initialState = fromJS({
loader: false,
snackbar: {
isOpen: false,
message: "",
severity: "",
duration: 1000,
position: "",
},
drawer: {
isOpen: false,
anchor: "left",
body: "",
},
});
export default function uiReducer(state = initialState, { type, payload }) {
switch (type) {
case Actions.OPEN_LOADER:
return state.set("loader", true);
case Actions.CLOSE_LOADER:
return state.set("loader", false);
case Actions.OPEN_DRAWER:
return state.set("drawer", fromJS(payload));
case Actions.CLOSE_DRAWER:
return state.set("drawer", initialState.get("drawer"));
case Actions.OPEN_SNACKBAR:
return state.set("snackbar", fromJS(payload));
case Actions.CLOSE_SNACKBAR:
return state.set("snackbar", initialState.get("snackbar"));
case HYDRATE:
return state;
default:
return state;
}
}
me/profile-setting:
import React from "react";
import Layout from "layout";
import { ProfileSetting } from "components/common";
import { DesktopMePages } from "components/desktop";
import { switchMePages } from "modules/me/actions";
import { detectDevice } from "utils";
import { wrapper } from "modules/store";
export default function ProfileSettings({ isMobile }) {
return isMobile ? <Mobile /> : <Desktop />;
}
function Desktop() {
return (
<Layout>
<DesktopMePages>
<ProfileSetting />
</DesktopMePages>
</Layout>
);
}
function Mobile() {
return (
<Layout isMobile={true} canBack={true}>
<ProfileSetting />
</Layout>
);
}
export const getServerSideProps = wrapper.getServerSideProps(
(store) => async (context) => {
const isMobile = detectDevice(context);
store.dispatch(switchMePages("Profile"));
return {
props: {
isMobile,
},
};
}
);
detectDevice:
export const detectDevice = context => {
const UA = context?.req?.headers['user-agent'];
const isMobile = Boolean(
UA.match(
/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile|WPDesktop/i,
),
);
return isMobile;
};
I am not able to dispatch action from the server with immutable Js.
Before immutable Js, everything was working fine.
It is showing error in .initialState.ui

How to debug "undefined is not an object" when navigating between screens

I'm trying when I press Login button to go to Drawer screen which contains all my other screens but I'm getting the following error:
TypeError: undefined is not an object (evaluating
'this.props.navigation.navigate')
Here is my DrawerScreen:
import React, {Component} from 'react';
import { Button, View, Text, Dimensions, ImageBackground } from 'react-native';
import { createStackNavigator, createAppContainer, createDrawerNavigator, DrawerItems } from 'react-navigation';
import HomeScreen from './HomeScreen';
import AboutScreen from './AboutScreen';
import Count from './CountScreen';
const DrawerContent = (props) => (
<View>
<ImageBackground
source={{uri:'https://cdn.pixabay.com/photo/2017/12/13/07/15/natural-3016177_960_720.jpg'}}
style={{}}
imageStyle= {{opacity: 0.7}}
>
<View
style={{
//backgroundColor: '#73a2ef',
height: 140,
alignItems: 'center',
justifyContent: 'center',
}}
>
<Text style={{ color: 'black', fontSize: 40, fontWeight: 'bold' }}>
Menu
</Text>
</View>
</ImageBackground>
<DrawerItems {...props} />
</View>
)
const WIDTF = Dimensions.get('window').width;
const DrawerConfig = {
drawerWidth: WIDTF*0.80,
drawertType: 'back',
}
const Drawer = createDrawerNavigator ({
Home: {
screen: HomeScreen
},
About: {
screen: AboutScreen
},
Count: {
screen: Count
},
},
{
drawerBackgroundColor: '#c7d1a7',
contentComponent: DrawerContent,
contentOptions: {
activeTintColor: 'blue',
style: {
flex: 1,
paddingTop: 15,
}
}},
DrawerConfig
);
const AppContainer = createAppContainer(Drawer);
export default AppContainer;
And here is my LogInScreen:
import React, {Component} from 'react';
import * as firebase from 'firebase';
import {Container, Content, Header, Form, Input, Item, Button, Label, Drawer} from 'native-base';
import {StyleSheet, Text} from 'react-native';
import AppContainer from './DrawerNavigatorNew';
const firebaseConfig = {
apiKey:
authDomain:
databaseURL:
projectId:
storageBucket:
};
firebase.initializeApp(firebaseConfig);
export default class LoginScreen extends React.Component {
constructor (props) {
super(props)
this.state =({
email:'',
password:'',
})
}
signUpUser = (email, password) => {
try {
if(this.state.password.length <6)
{
alert("Please enter atleast 6 characters")
return;
}
firebase.auth().createUserWithEmailAndPassword(email, password)
}
catch (error){
console.log(error.toString())
}
}
loginUser =(email, password) => {
try{
firebase.auth().signInWithEmailAndPassword(email, password).then(function(user){
console.log(user)
})
}
catch (error) {
console.log(error.toString())
}
}
render() {
const {navigate} = this.props.navigation;
return (
<Container style={styles.container}>
<Form>
<Item floatingLabel>
<Label> Email </Label>
<Input
name='email'
autoCorrect={false}
autoCapitalize='none'
onChangeText={(email)=> this.setState({email})}
/>
</Item>
<Item floatingLabel>
<Label> Password </Label>
<Input
name='password'
secureTextEntry={true}
autoCorrect={false}
autoCapitalize='none'
onChangeText={(password)=> this.setState({password})}
/>
</Item>
<Button style={{marginTop: 10}}
full
rounded
success
onPress = {()=> this.loginUser(this.state.email,this.state.password) || navigate(AppContainer)}
>
<Text> Login </Text>
</Button>
<Button style={{marginTop: 10}}
full
rounded
primary
onPress = {()=> this.signUpUser(this.state.email,this.state.password)}
>
<Text style={{color: 'white' }}> Sign Up </Text>
</Button>
</Form>
</Container>
);
}
}
const styles = StyleSheet.create ({
container:{
flex: 1,
backgroundColor: 'white',
justifyContent: 'center',
padding: 10
}
})
And the Error:
I misread the code. 'Navigate' is a command to move the screen. The 'createDrawenavigator' must open the drawer.
Can you try this Code?
onPress = {()=> this.loginUser(this.state.email,this.state.password) || this.props.navigation.openDrawer();}
Change the Navigator configuration if you want to move the screen.
createStackNavigator({
A: {
screen: AScreen,
navigationOptions: () => ({
title: `A`,
headerBackTitle: 'A much too long text for back button from B to A',
headerTruncatedBackTitle: `to A`
}),
},
B: {
screen: BScreen,
navigationOptions: () => ({
title: `B`,
}),
}
});

How to add product in cart using react native?

I'm working in the react-native android app which connects WordPress woocommerce API and gets data from WordPress and process it. Everything working fine, but I'm a newbie to react-native and can't trigger out how to add a product in the cart. Also, need to show the product in cart page Below I added my code. I hope will get help.
import React, { Component } from "react";
import {
View,
Text,
StyleSheet,
TouchableOpacity,
Platform,
StatusBar,
Image,
TouchableHighlight, ToolbarAndroid,
FlatList,
ScrollView,TextInput,
AsyncStorage
} from "react-native";
import HTMLView from 'react-native-htmlview';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { StackNavigator } from "react-navigation";
import {Icon, Button, Container, Header, Content,Left ,Right,Item,Input,Card,CardItem} from 'native-base'
import { Ionicons,FontAwesome } from '#expo/vector-icons'
import FAIcon from 'react-native-vector-icons/FontAwesome'
import * as CartAction from '../Actions/CartActions';
//Constant declaration
export const GET_PRODUCTS_SUCCESS = 'GET_PRODUCTS_SUCCESS'
export const GET_PRODUCTS_FAILED = 'GET_PRODUCTS_FAILED';
export const GET_CART_SUCCESS = 'GET_CART_SUCCESS';
export const ADD_TO_CART_SUCCESS = 'ADD_TO_CART_SUCCESS';
export const REMOVE_FROM_CART_SUCCESS = 'REMOVE_FROM_CART_SUCCESS';
class Products extends Component {
constructor(props) {
super(props);
this.state = { quantity: 1 };
}
//decrease quantity working
decreaseQuantity = () => {
if(this.state.quantity <= 1) {
return;
} else {
this.setState({
quantity: this.state.quantity - 1
});
}
}
//increase quantity working
increaseQuantitiy = () => {
this.setState({
quantity: this.state.quantity - 1 + 2
});
}
//add to cart NOT WORKING
addToCart(product, quantity) {
return (dispatch) => {
const cartItem = {
"id": product.id,
"image": product.images[0].src,
"name": product.name,
"quantity": quantity
}
dispatch({
type: types.ADD_TO_CART_SUCCESS,
item: cartItem
});
}
}
//Sidemenu Icon
static navigationOptions ={
drawerIcon:(
<FontAwesome name="home" size={30} color="black" />
)
}
//Render Block
render() {
const product = this.props.navigation.state.params.product;
return (
<Container>
//Product View
<ScrollView>
<Image style={styles.image} source={{ uri: product.images[0].src }} />
<View style={{ alignItems: 'center', justifyContent: 'center' }}>
<Text style={{fontSize:18,fontWeight:'bold'}}>{product.name}</Text>
<Text> ₹ {product.price}</Text>
</View>
<View style={{ display: 'flex', flexDirection: 'row', padding: 10, marginLeft: 20, marginBottom: 20 }}>
<View style={{ display: 'flex', flexDirection: 'row', justifyContent: 'center',marginTop:10 }}>
<TouchableOpacity style={styles.decreaseButton} onPress={this.decreaseQuantity}>
<Text> - </Text>
</TouchableOpacity>
<TextInput
style={styles.input}
onChangeText={(quantity) => this.setState({ quantity })}
value={`${this.state.quantity}`}
keyboardType="numeric"
/>
<TouchableOpacity style={styles.inceaseButton} onPress={this.increaseQuantitiy} >
<Text> + </Text>
</TouchableOpacity>
</View>
// ---------------- Adding to cart not working also need to show this product in cart page----------------
<TouchableOpacity style={styles.button} onPress={() => this.addToCart(product, this.state.quantity)} >
<Text style={{ color: '#fff' }}> ADD TO CART </Text>
</TouchableOpacity>
</View>
<HTMLView style={styles.html} value={product.description} />
</ScrollView>
</Container>
)
}
}
export default Products;

Resources