can't submit a form when using FlatLists - javascript

Previously, I was rendering and mapping some data using another component called UserList. However, now I have changed it to a FlatList
When I was using {/* <UserList onSendRequest={onSendRequest} data={userData}></UserList> */}, every time I clicked on the button, the handleSubmit function was called successfully.
However, now I am using FlatList. Nothing happens when I click on the button. The handle submit does not run and I don't see anything from the flatList. What am I doing wrong?
return (
<SafeAreaView>
<View>
<View style={styles.searchTopContainer}>
<View style={styles.searchTopTextContainer}>
<Text>
Cancel
</Text>
</View>
<View>
<Formik
initialValues={initialValues}
onSubmit={handleSubmitForm}
validationSchema={validationSchema}>
{({ handleChange, handleBlur, handleSubmit, values }) => (
<View style={styles.searchFieldContainer}>
<View style={styles.form}>
<FieldInput
handleChange={handleChange}
handleBlur={handleBlur}
value={values.input}
fieldType="input"
icon="user"
placeholderText="Email or Phone Number or Name"
/>
<ErrorMessage
name="input"
render={(msg) => (
<Text style={styles.errorText}>{msg}</Text>
)}
/>
</View>
<View style={styles.buttonContainer}>
<Button
rounded
style={styles.searchButton}
onPress={handleSubmit}>
<Text style={styles.searchButtonText}>Search </Text>
</Button>
</View>
</View>
)}
</Formik>
</View>
{/* <UserList onSendRequest={onSendRequest} data={userData}></UserList> */}
{userData !== null &&
<FlatList
data={userData.users}
horizontal={false}
renderItem={({ item }) => (
<SingleUser
user={item}
onSendRequest={onSendRequest}
/>
)}
keyExtractor={(item) => item.id.toString()}
/>
}
</View>
</View>
</SafeAreaView>
);
};
UserList.tsx:
export const UserList: React.FunctionComponent<UserProps> = ({
data,
onSendRequest,
}) => {
if (!data) return null;
return (
<View style={styles.users}>
{data.users.nodes.map(
(item: { firstName: string; lastName: string; id: number }) => {
const userName = item.firstName.concat(' ').concat(item.lastName);
return (
<View style={styles.item} key={item.id}>
<Thumbnail
style={styles.thumbnail}
source={{
uri:
'https://cdn4.iconfinder.com/data/icons/avatars-xmas-giveaway/128/afro_woman_female_person-512.png',
}}></Thumbnail>
<Text style={styles.userName}>{userName}</Text>
<View style={styles.addButtonContainer}>
<Button
rounded
style={styles.addButton}
onPress={() => onSendRequest(Number(item.id))}
>
<Icon name="plus" size={moderateScale(20)} color="black" />
</Button>
</View>
</View>
);
},
)}
</View>
);
};

Related

React native : Flatlist inside scrollview

My goal is for this entire block to be scrollable.
I tried all kinds of ways to achieve the goal but without success.
I tried with ListHeaderComponent and moved the entire top view to it and it didn't work.
And I also tried <FlatList nestedScrollEnabled />
And it didn't work either.
What is the correct way to reach the scroll?
I come from here :
const renderAccordians = () => {
const items: JSX.Element[] = [];
areaData.forEach(item => {
items.push(<Accordian item={item} key={item.title} />);
});
return items;
};
To here :
return (
<View>
<View style={styles.row}>
<TouchableOpacity onPress={() => onClickFather()}>
<MaterialIcons size={24} name={data.checked ? 'check-box' : 'check-box-outline-blank'} color={'black'} />
</TouchableOpacity>
<Text style={[styles.title]}>{data.title}</Text>
<TouchableOpacity style={styles.row} onPress={() => toggleExpand()}>
<MaterialIcons name={expanded ? 'arrow-drop-up' : 'arrow-drop-down'} size={30} color={'black'} />
</TouchableOpacity>
</View>
<View style={styles.parentHr} />
{expanded && (
<FlatList
data={data.data}
numColumns={1}
scrollEnabled={false}
renderItem={({ item, index }) => (
<View>
<TouchableOpacity style={[styles.childRow, styles.button]} onPress={() => onClick(index)}>
<MaterialIcons
size={24}
name={item.checked ? 'check-box' : 'check-box-outline-blank'}
color={'black'}
/>
<Text style={[styles.itemInActive]}>{item.key}</Text>
</TouchableOpacity>
<View style={styles.childHr} />
</View>
)}
/>
)}
</View>
);
Since your FlatList will be part of an Accordion component, you "can't" embed the ExpandButton inside the Flatlist > ListHeaderComponent ... cause It'll simply hide the whole FlatList along with it's Header when you collapse your accorddion...
keyExtractor is also missing in your FlatList .. I added index as a key here which is not recommended BTW, you better use a unique field in your listItem like id...
return (
<View style={{ flex: 1}}> // <<--- Look here
<View style={styles.row}>
<TouchableOpacity onPress={() => onClickFather()}>
<MaterialIcons
size={24}
name={data.checked ? 'check-box' : 'check-box-outline-blank'}
color={'black'}
/>
</TouchableOpacity>
<Text style={[styles.title]}>{data.title}</Text>
<TouchableOpacity style={styles.row} onPress={() => toggleExpand()}>
<MaterialIcons
name={expanded ? 'arrow-drop-up' : 'arrow-drop-down'}
size={30}
color={'black'}
/>
</TouchableOpacity>
</View>
<View style={styles.parentHr} />
{expanded && (
<FlatList
data={data.data}
numColumns={1}
scrollEnabled={true} // <<--- Look here
keyExtractor={(_, index) => index.toString()} // <<=== Look here
contentContainerStyle={{flexGrow: 1}} // <<--- Look here
renderItem={({ item, index }) => (
<View>
<TouchableOpacity
style={[styles.childRow, styles.button]}
onPress={() => onClick(index)}
>
<MaterialIcons
size={24}
name={item.checked ? 'check-box' : 'check-box-outline-blank'}
color={'black'}
/>
<Text style={[styles.itemInActive]}>{item.key}</Text>
</TouchableOpacity>
<View style={styles.childHr} />
</View>
)}
/>
)}
</View>
);
If it does not work, I think you should create a component and use map datalist to render all the items and putting them into the ScrollView tag.
<ScrollView
style={styles.messageContain}
ref={ref => {
this.scrollView = ref;
}}
{data.data.map((item, index) => {
return <YourComponent key={index} data={item} />;
})}
</ScrollView>

How can conditional rendering for array map

I have condition for profile page
I want to show user profile data
name . age etc..So I map array to get each user data
but problem is when there is no data in firestore , this profile page is empty
this is really disappointed
I want to conditional rendering the following rendering
But error is
jsx expression must have one parent element
so how can render this correctly
return (
<SafeAreaView style={styles.container}>
{values.map((value)=>(
<React.Fragment key={value.id}>
<View style={styles.header}></View>
<Image style={styles.avatar} source={{uri : value.photo}}/>
<View style={styles.body}>
<View style={styles.bodyContent}>
<Text style={styles.name}>{value.displayName}</Text>
<View style={styles.label}>
<Text >My Job is - </Text>
<Text>{value.job}</Text>
</View>
<View style={styles.label}>
<Text>My Age is - </Text>
<Text >{value.age}</Text>
</View>
<View style={styles.label}>
<Text>My Gender is - </Text>
<Text >{value.gender}</Text>
</View>
<View style={styles.label}>
<Text>I want to meet - </Text>
<Text >{value.interestIn}</Text>
</View>
</View>
</View>
</React.Fragment>
))}
<View style={tw("p-10 flex-row items-center justify-between px-5")}>
<Pressable
style={
tw('p-3 rounded-xl bg-red-400')} onPress={goedit}>
<Text style={styles.text}>Edit Profile</Text>
</Pressable>
<Pressable
style={
tw('p-3 rounded bg-red-400')} onPress={logout}>
<Text style={styles.text}>LOGOUT</Text>
</Pressable>
</View>
</SafeAreaView>
)
I want to show user profile page as template even no data in firestore
can someone help me
Just add a <> ontop of the map and then </> on the bottom to close it. If you need flex then you can switch out the <></> for
You could try something like this, but paste your logic inside if statement:
const renderValues = () => {
values.map((value) => {
if (value) {
return (
<View>
<Text>data</Text>
</View>
);
} else {
return <View>no data</View>;
}
});
};
return <>{renderValues()}</>;
const renderValues = () => {
values.map((value) => {
if (value) {
return (
<React.Fragment key={value.id}>
<View style={styles.header} />
<Image style={styles.avatar} source={{ uri: value.photo }} />
<View style={styles.body}>
<View style={styles.bodyContent}>
<Text style={styles.name}>{value.displayName}</Text>
<View style={styles.label}>
<Text>My Job is - </Text>
<Text>{value.job}</Text>
</View>
<View style={styles.label}>
<Text>My Age is - </Text>
<Text>{value.age}</Text>
</View>
<View style={styles.label}>
<Text>My Gender is - </Text>
<Text>{value.gender}</Text>
</View>
<View style={styles.label}>
<Text>I want to meet - </Text>
<Text>{value.interestIn}</Text>
</View>
</View>
</View>
</React.Fragment>
);
} else {
return <View>no data</View>;
}
});
};
return (
<SafeAreaView style={styles.container}>
<>
{renderValues()}
<View style={tw('p-10 flex-row items-center justify-between px-5')}>
<Pressable style={tw('p-3 rounded-xl bg-red-400')} onPress={goedit}>
<Text style={styles.text}>Edit Profile</Text>
</Pressable>
<Pressable style={tw('p-3 rounded bg-red-400')} onPress={logout}>
<Text style={styles.text}>LOGOUT</Text>
</Pressable>
</View>
</>
</SafeAreaView>
);

How to navigate between different components based on conditions in react native

I am building a a mobile app in react native in which I have videos and audios coming in same data array. Now I am rendering them into a flatlist and audios and videos are coming together randomly. Now I want that If I click on the audio file it should navigate to Audios component and if I click on any video it should navigate to Videos Component. But I don't know how to filter and navigate to their respective components. Kindly help me. Thank you
My code
Main File: It is navigating to Audio component either I click on audio file or either on video file
<FlatList
horizontal
data={latestuploads}
keyExtractor={item => item.id}
renderItem={({item}) => {
return (
<ScrollView horizontal={true}>
<Card transparent style={{width: 170}}>
<TouchableOpacity
onPress={() =>
this.props.navigation.navigate('Audio', {id: item.id})
}>
<CardItem>
<ImageBackground
source={{uri: item.image_url}}
style={styles.image}>
<Image
source={require('../assets/play-icon.png')}
style={styles.icon}
/>
</ImageBackground>
</CardItem>
</TouchableOpacity>
<CardItem cardBody>
<Text numberOfLines={1} style={styles.title}>
{item.title}
</Text>
</CardItem>
<CardItem cardBody>
<Text style={styles.speaker}> {item.speaker} </Text>
</CardItem>
</Card>
</ScrollView>
);
}}
/>
I suppose you're getting file extension example .mp4/.mp3 etc or Audio/Video flag from your data array.
Create a function that takes file info example:
navigateTo = (fileinfo) => {
// const filetype = check for file type, Audio/Video or file extension
if (filetype === 'Audio'){
this.props.navigation.navigate('Audio', {id: fileinfo.id})
} else {
this.props.navigation.navigate('Video', {id: fileinfo.id})
}
Pass this to your TouchableOpacity:
<TouchableOpacity
onPress={() => navigateTo(item)}>
// your code here
</TouchableOpacity>
constructor()
{
super(props)
this.state = {
ItemindexChecked: "",
}
this.Dataarrayholder = latestuploads;
}
............................your code ............
DataFilter(p_value)
{
const newData = this.Dataarrayholder.filter(function (item) {
const itemData = item.value ? item.value.toUpperCase() : ''.toUpperCase();
const textData = p_value.toUpperCase();
return itemData.indexOf(textData) > -1;
if (p_value != "")
{
if (newData == 0) {
return
}
else
{
this.props.navigation.navigate('Audio', { id: newData[0].id });
}
}
});
}
...........................................your code ..............
<FlatList
horizontal
data={latestuploads}
keyExtractor={item => item.id}
renderItem={({ item }) => {
return (
<ScrollView horizontal={true}>
<Card transparent style={{ width: 170 }}>
<TouchableOpacity
//onPress={() =>
// // this.props.navigation.navigate('Audio', { id: item.id })
// }
onPress={() => { this.DataFilter(item.value), this.setState({ ItemindexChecked: item.key }) }}
>
<CardItem>
<ImageBackground
source={{ uri: item.image_url }}
style={styles.image}>
<Image
source={require('../assets/play-icon.png')}
style={styles.icon}
/>
</ImageBackground>
</CardItem>
</TouchableOpacity>
<CardItem cardBody>
<Text numberOfLines={1} style={styles.title}>
{item.title}
</Text>
</CardItem>
<CardItem cardBody>
<Text style={styles.speaker}> {item.speaker} </Text>
</CardItem>
</Card>
</ScrollView>
);
}}
/>
maybe it helpful for you

How I can handle multiple checkbox and basis of that show and hide input fields and update to server in react native

In my code there are 2 dropdowns, 4 checkboxes, 4 input fields and one button.
Basically I have to update these fields on button click.
Problem with ckeck box .
I have to make checkbox "checked={true/false}" on condition basis, and I have to take these value and update the server:
1 [] Emal [] sms [] fax (all are unchecked )
Suppose I click on email the email should be checked and one Email input field should appear. And if again I uncheck the checkbox, the input field should be hidden.
If the value is checked Y value should go to server else N value if unchecked when I press the button below .
Basically there are multiple checkboxes and I have to update their value to server . Below Is UX link please see once .
https://xd.adobe.com/view/2b0336f6-6ff6-40ae-6653-f71e080dd0da-5d32/?fullscreen
import React, { Component } from 'react';
import { ImageBackground, ScrollView, TouchableOpacity, View, Platform, Image } from 'react-native';
import { Button, Text, Item, Input, Icon, Form, ListItem, CheckBox, Body, List } from 'native-base';
import Header from '../../ui/header';
import TextFieldTypeClear from '../../ui/textFieldTypeClear';
import SelectField from '../../ui/selectField';
import { PrimaryBtn } from '../../ui/buttons';
import BG from '../../../images/bg.jpg';
import styles from '../../simSwap/SimSwap.style';
import { RegularText, SmallText } from '../../ui/text';
import { ACCOUNT_OWNER,ADDRESS,CYCLE,EMAIL,PHONE,PERIODICITY,CURRENCY,LANGUAGE,EDIT,MAIL,FAX,POST,SMS,WHATSAPP } from '../../../images';
import _ from 'lodash';
const styless = {
icon:{
marginRight:5, marginTop:3
},
label:{
fontSize:14, color:'grey'
}
}
const Label = ({img, textLabel}) =>{
return (
<View style={{flexDirection:'row'}}>
<Image style={styless.icon} source={img}/>
<Text style={styless.label}>{textLabel}</Text>
</View>
);
}
class UpdateBillPreferences extends Component {
constructor(props) {
super(props);
const {navigation,clmmasterData} =this.props;
this.state = {
title: 'Update Bill Preferences',
mobile: navigation.state.params.customer.service.serviceNumber,
icon: 'sim',
email: '',
smsNum: '',
faxNum: '',
isBillByEmail : navigation.state.params.customerInfo[0].billingPreferenceDetails.isBillByEmail,
isBillBySms : navigation.state.params.customerInfo[0].billingPreferenceDetails.isBillByFax,
isBillByFax : navigation.state.params.customerInfo[0].billingPreferenceDetails.isBillBySms,
languageAndCurrecny:{
preferredLanguage: navigation.state.params.customerInfo[0].billingPreferenceDetails.presentationLanguageCode,
},
currencyChangedValue:{
preferredCurrency: navigation.state.params.customerInfo[0].billingPreferenceDetails.preferedCurrencyCode,
}
};
}
componentDidMount() {
}
OnButtonClick = async (preferredLanguage, preferredCurrency,email,smsNum,faxNum) => {
const { OnButtonClick } = this.props;
await OnButtonClick(preferredLanguage, preferredCurrency,email,smsNum,faxNum);
this.setState({
preferredCurrency:'',
preferredLanguage:'',
email :'',
smsNum :'',
faxNum :''
})
}
languageChanged = (key, val) => {
this.handleChange({ field: "preferredLanguage" }, val);
};
handleChange = (props, e) => {
let tempObj = this.state.languageAndCurrecny;
tempObj[props.field] = e;
this.setState({ preferredLanguage: tempObj });
};
currencyChanged = (key, val) => {
this.handleChange2({ field: "preferredCurrency" }, val);
};
handleChange2 = (props, e) => {
let tempObj = this.state.currencyChangedValue;
tempObj[props.field] = e;
this.setState({ preferredCurrency: tempObj });
};
handleChange1 = () => {
let isBillByEmail=this.state.isBillByEmail;
console.log("-----------------------clicked-------");
this.setState(previousState => {
return { isBillByEmail: !previousState.checked };
})
console.log("----------isBillByEmail--------------------",isBillByEmail);
}
render() {
let { title, mobile, icon,languageAndCurrecny,currencyChangedValue,isBillByEmail } = this.state;
const { navigation,clmmasterData} = this.props;
const {billingAddressDetails,billingPreferenceDetails} = navigation.state.params.customerInfo[0];
const {masterData , language} = clmmasterData;
let submitBtn = { label: 'Submit', OnSubmit: this.onSubmit };
let currencyData=[];
masterData.preferredCurrency.map(({ code: value, name: label }) => {
currencyData.push({ value, label });
});
let languageData=[];
masterData.language.map(({ code: value, name: label }) => {
languageData.push({ value, label });
});
return (
<ImageBackground source={BG} style={styles.imgBG}>
<ScrollView>
<View style={styles.container}>
<View>
<Header title={title} subtitle={mobile} icon={icon} navigation={navigation}/>
</View>
<View style={styles.contentContainer}>
<View style={{ padding: 20 }}>
<Form style={{ width: '100%' }}>
<SelectField
label="Presentation Language"
node="presentationLanguage"
options={languageData}
value={languageAndCurrecny.preferredLanguage}
onChange={this.languageChanged}
that={this}
setIcon={true}
img="LANGUAGE"
/>
<SelectField
label="Preferred Currency"
options={currencyData}
value={currencyChangedValue.preferredCurrency}
node="preferredCurrency"
onChange={this.currencyChanged}
that={this}
setIcon={true}
img="CURRENCY"
/>
<View style={{flexDirection:'column', marginBottom:15}}>
<View>
<Text style={{ color: 'grey', marginBottom: 15, marginTop:10, fontSize:14 }}>Preference</Text>
</View>
<View style={{flexDirection:'row', marginLeft:-10}}>
<View style={{flex:1}}>
<CheckBox color="#00678f" checked={billingPreferenceDetails.isBillByPost === "Y" ? true : false}/>
</View>
<View style={{flex:1}}>
<Text style={{fontSize:14}}>Post</Text>
</View>
<View style={{flex:1}}>
<CheckBox color="#00678f" checked={isBillByEmail==='Y'?true : false} onPress={() =>this.handleChange1()}/>
</View>
<View style={{flex:1}}>
<Text style={{fontSize:14}}>Email</Text>
</View>
<View style={{flex:1}}>
<CheckBox color="#00678f" checked={true} onPress={() =>this.handleChange()}/>
</View>
<View style={{flex:1}}>
<Text style={{fontSize:14}}>SMS</Text>
</View>
<View style={{flex:1}}>
<CheckBox color="#00678f" checked={true} onPress={() =>this.handleChange()}/>
</View>
<View style={{flex:1}}>
<Text style={{fontSize:14}}>FAX</Text>
</View>
</View>
</View>
<View style={{flexDirection:'column', marginBottom:15}}>
<View style={{marginTop:10, marginBottom:10, marginLeft:-3}}>
<Label img={ADDRESS} textLabel="Address"/>
</View>
<View>
<RegularText style={{ fontWeight: 'normal' }} text={`${billingAddressDetails.address1}, ${billingAddressDetails.address2}, ${billingAddressDetails.cityName}, ${billingAddressDetails.state}, ${billingAddressDetails.country}`} textColor="black" />
</View>
</View>
<View style={{marginBottom:15}}>
{billingPreferenceDetails.isBillByEmail === 'Y' &&
<View>
<Label img={EMAIL} textLabel="Email"/>
<Item style={{borderColor: '#00fff', borderBottomWidth:1, marginLeft:0}}>
<Input
value={this.state.email}
onChangeText={(text) => this.setState({email:text})}
/>
</Item>
</View>}
{billingPreferenceDetails.isBillBySms === 'Y' &&
<View>
<Label img={EMAIL} textLabel="SMS"/>
<Item style={{borderColor: '#00fff', borderBottomWidth:1, marginLeft:0}}>
<Input
value={this.state.smsNum}
onChangeText={(text) => this.setState({smsNum:text})}
/>
</Item>
</View>}
{billingPreferenceDetails.isBillByFax === 'Y' &&
<View>
<Label img={EMAIL} textLabel="FAX"/>
<Item style={{borderColor: '#00fff', borderBottomWidth:1, marginLeft:0}}>
<Input
value={this.state.faxNum}
onChangeText={(text) => this.setState({faxNum:text})}
/>
</Item>
</View>}
</View>
<View style={{ marginTop: 50 }}>
<PrimaryBtn label={'submit'} disabled={false} onPress={()=> this.OnButtonClick(this.state.preferredLanguage,this.state.preferredCurrency,
this.state.email,this.state.smsNum,this.state.faxNum)}/>
</View>
</Form>
</View>
</View>
</View>
</ScrollView>
</ImageBackground>
);
}
}
export default UpdateBillPreferences;
// Checkbox part where I am facing problem .
Props Value
isBillByEmail: "N"
isBillByFax: "Y"
isBillByPost: "Y"
isBillBySms: "N"
<View style={{flexDirection:'column', marginBottom:15}}>
<View>
<Text style={{ color: 'grey', marginBottom: 15, marginTop:10, fontSize:14 }}>Preference</Text>
</View>
<View style={{flexDirection:'row', marginLeft:-10}}>
<View style={{flex:1}}>
<CheckBox color="#00678f" checked={billingPreferenceDetails.isBillByPost === "Y" ? true : false}/>
</View>
<View style={{flex:1}}>
<Text style={{fontSize:14}}>Post</Text>
</View>
<View style={{flex:1}}>
<CheckBox color="#00678f" checked={isBillByEmail==='Y'?true : false} onPress={() =>this.handleChange1()}/>
</View>
<View style={{flex:1}}>
<Text style={{fontSize:14}}>Email</Text>
</View>
<View style={{flex:1}}>
<CheckBox color="#00678f" checked={true} onPress={() =>this.handleChange()}/>
</View>
<View style={{flex:1}}>
<Text style={{fontSize:14}}>SMS</Text>
</View>
<View style={{flex:1}}>
<CheckBox color="#00678f" checked={true} onPress={() =>this.handleChange()}/>
</View>
<View style={{flex:1}}>
<Text style={{fontSize:14}}>FAX</Text>
</View>
</View>
</View>
<View style={{flexDirection:'column', marginBottom:15}}>
<View style={{marginTop:10, marginBottom:10, marginLeft:-3}}>
<Label img={ADDRESS} textLabel="Address"/>
</View>
<View>
<RegularText style={{ fontWeight: 'normal' }} text={`${billingAddressDetails.address1}, ${billingAddressDetails.address2}, ${billingAddressDetails.cityName}, ${billingAddressDetails.state}, ${billingAddressDetails.country}`} textColor="black" />
</View>
</View>
<View style={{marginBottom:15}}>
{billingPreferenceDetails.isBillByEmail === 'Y' &&
<View>
<Label img={EMAIL} textLabel="Email"/>
<Item style={{borderColor: '#00fff', borderBottomWidth:1, marginLeft:0}}>
<Input
value={this.state.email}
onChangeText={(text) => this.setState({email:text})}
/>
</Item>
</View>}
{billingPreferenceDetails.isBillBySms === 'Y' &&
<View>
<Label img={EMAIL} textLabel="SMS"/>
<Item style={{borderColor: '#00fff', borderBottomWidth:1, marginLeft:0}}>
<Input
value={this.state.smsNum}
onChangeText={(text) => this.setState({smsNum:text})}
/>
</Item>
</View>}
{billingPreferenceDetails.isBillByFax === 'Y' &&
<View>
<Label img={EMAIL} textLabel="FAX"/>
<Item style={{borderColor: '#00fff', borderBottomWidth:1, marginLeft:0}}>
<Input
value={this.state.faxNum}
onChangeText={(text) => this.setState({faxNum:text})}
/>
</Item>
</View>}
</View>
<View style={{ marginTop: 50 }}>
<PrimaryBtn label={'submit'} disabled={false} onPress={()=> this.OnButtonClick(this.state.preferredLanguage,this.state.preferredCurrency,
this.state.email,this.state.smsNum,this.state.faxNum)}/>
</View>
</Form>
</View>
</View>
Please help..Thanks

How to pass data item to react native modal

I am trying to pass data item to a react native modal on a click of a button 'view modal' but it seems I am missing something in my code.
Here is the data object that is been looped to show on the timeline screen
Object {
"farmer_id": "4",
"farmer_name": "Joshua Adebisi",
"id": "4",
"product_description": "The grains of rice is good for healthy.It is durable,I
t is Awesome Intesrest buyers can contact via contact 08073047104.",
"product_image": "https://via.placeholder.com/600/cb47e2",
"product_name": "5kg Grains of Rice",
"profile_img": "https://via.placeholder.com/150/cb47e2",
"uploaded_time": "2019-06-10 23:48:04",
}
Object {
"farmer_id": "3",
"farmer_name": "Omolewa Stephen",
"id": "3",
"product_description": "The grains of rice is good for healthy.It is durable,I
t is Awesome Intesrest buyers can contact via contact 08073047104.",
"product_image": "https://via.placeholder.com/600/4dcdf6",
"product_name": "5kg Grains of Rice",
"profile_img": "https://via.placeholder.com/150/cb47e2",
"uploaded_time": "2019-06-10 23:48:04",
}
Object {
"farmer_id": "2",
"farmer_name": "Salami Paul",
"id": "2",
"product_description": "The grains of rice is good for healthy.It is durable,I
t is Awesome Intesrest buyers can contact via contact 08073047104.",
"product_image": "https://via.placeholder.com/600/cb47e2",
"product_name": "5kg Grains of Rice",
"profile_img": "https://via.placeholder.com/150/cb47e2",
"uploaded_time": "2019-06-10 23:48:04",
}
Object {
"farmer_id": "1",
"farmer_name": "Adebiyi Samuel",
"id": "1",
"product_description": "The grains of rice is good for healthy.It is durable,T
he grains of rice is good for healthy.It is durable.It is Awesome Intesrest buye
rs can contact via contact 08073047104.
",
"product_image": "https://via.placeholder.com/600/4dcdf6",
"product_name": "5kg Grains of Beans",
"profile_img": "https://via.placeholder.com/150/cb47e2",
"uploaded_time": "2019-06-11 02:56:53",
}
Here is the timeline code
import React, {Component} from 'react';
import {TextInput,Modal,Alert,TouchableHighlight,StyleSheet,RefreshControl ,ScrollView,Dimensions,Image,StatusBar,ActivityIndicator,Text, View,TouchableOpacity,KeyboardAvoidingView} from 'react-native';
import { createBottomTabNavigator,createStackNavigator,createSwitchNavigator, createAppContainer} from "react-navigation";
let {height, width} = Dimensions.get('window');
import { Ionicons } from '#expo/vector-icons';
import { Font } from 'expo';
import { AsyncStorage } from 'react-native';
export default class Timeline extends Component {
constructor(props){
super(props)
console.log(props)
this.state = {
username: '',
photo: '',
email: '',
userId: '',
address: '',
timeline: [],
modalVisible: false,
refreshing: false
}
}
setModalVisible(visible) {
this.setState({modalVisible: visible});
}
Home = () => {
alert("Home");
}
PostTimeline = () => {
return fetch( "http://texotrack.com/api/user/timeline.php", {
method: "POST",
headers:{
'Content-Type': 'application/json'
},
body: JSON.stringify({
action: 'fetch'
})
}).then((response) => response.json()).then((responseJsonFromServer) => {
this.setState({
timeline: responseJsonFromServer
});
})
}
componentDidMount(){
this.PostTimeline();
AsyncStorage.getItem("key").then((data) =>{
const val = JSON.parse(data);
this.setState({
username: data.name,
photo: data.photo,
email: data.email,
userId: data.id,
address: data.address
})
})
}
render() {
const timeLineList = this.state.timeline.map((data) => {
console.log(data);
const thumbnail = data.profile_img;
const product_image = data.product_image;
return (
<View elevation={5} key={data.id} style={styles.card}>
<Modal
animationType="fade"
transparent={false}
visible={this.state.modalVisible}
key={data.id}
onRequestClose={() => {
alert('Modal has been closed.');
}}>
<View style={{margin: 10}}>
<Text style={styles.headerText}>Product details: {data.product_name}</Text>
<View style={styles.cardheader}>
<View style={styles.miniheader}>
<Image style={styles.thumbnail} source={{uri: thumbnail}} />
<Text style={styles.thumb_name}>{data.farmer_name}</Text>
</View>
<Text style={styles.timestamp}>{data.uploaded_time}</Text>
</View>
<View style={styles.cardbody}>
<Image style={styles.cardbody_image} source={{uri: product_image}}/>
<Text style={styles.p_name}>{data.product_name}</Text>
<Text style={styles.p_desc}>{data.product_description}</Text>
<View>
</View>
</View>
<TouchableHighlight
onPress={() => {
this.setModalVisible(!this.state.modalVisible);
}}>
<Text>Close</Text>
</TouchableHighlight>
</View>
</Modal>
<View style={styles.cardheader}>
<View style={styles.miniheader}>
<Image style={styles.thumbnail} source={{uri: thumbnail}} />
<Text style={styles.thumb_name}>{data.farmer_name}</Text>
</View>
<Text style={styles.timestamp}>{data.uploaded_time}</Text>
</View>
<View style={styles.cardbody}>
<Image style={styles.cardbody_image} source={{uri: product_image}}/>
<Text style={styles.p_name}>{data.product_name}</Text>
<Text style={styles.p_desc}>{data.product_description}</Text>
<View>
<TouchableOpacity
onPress={() => {
this.setModalVisible(true);
}} style={styles.buttonContainer}>
<Text style={styles.buttonText}>Show Modal</Text>
</TouchableOpacity>
</View>
</View>
</View>
)
});
return (
<View style={styles.container}>
<View elevation={5} style={styles.mainheader}>
<Text style={styles.iconTop} onPress={() => this.PostTimeline()}>
<Ionicons name="md-refresh" size={32} color="black" />
</Text>
<Text style={styles.headerTitle}>Home</Text>
<Text style={styles.iconTop} onPress={() => this.Home()}>
<Ionicons name="md-home" size={32} color="black" />
</Text>
</View>
<View style={styles.content}>
<View style={{padding: 10}}>
<Text style={styles.headerText}><Ionicons name="md-cart" size={26} color="black" /> Marketplace</Text>
</View>
<View style={{flex:1}}>
<ScrollView alwaysBounceVertical={true} contentContainerStyle={{ flexGrow: 1}} enabled bounces={true}>
{timeLineList}
</ScrollView>
</View>
</View>
</View>
);
}
}
The focus is on the render method here with the modal, how do I pass the data item to the modal when each button is clicked to view the details. Thanks
render() {
const timeLineList = this.state.timeline.map((data) => {
console.log(data);
const thumbnail = data.profile_img;
const product_image = data.product_image;
return (
<View elevation={5} key={data.id} style={styles.card}>
<Modal
animationType="fade"
transparent={false}
visible={this.state.modalVisible}
key={data.id}
onRequestClose={() => {
alert('Modal has been closed.');
}}>
<View style={{margin: 10}}>
<Text style={styles.headerText}>Product details: {data.product_name}</Text>
<View style={styles.cardheader}>
<View style={styles.miniheader}>
<Image style={styles.thumbnail} source={{uri: thumbnail}} />
<Text style={styles.thumb_name}>{data.farmer_name}</Text>
</View>
<Text style={styles.timestamp}>{data.uploaded_time}</Text>
</View>
<View style={styles.cardbody}>
<Image style={styles.cardbody_image} source={{uri: product_image}}/>
<Text style={styles.p_name}>{data.product_name}</Text>
<Text style={styles.p_desc}>{data.product_description}</Text>
<View>
</View>
</View>
<TouchableHighlight
onPress={() => {
this.setModalVisible(!this.state.modalVisible);
}}>
<Text>Close</Text>
</TouchableHighlight>
</View>
</Modal>
<View style={styles.cardheader}>
<View style={styles.miniheader}>
<Image style={styles.thumbnail} source={{uri: thumbnail}} />
<Text style={styles.thumb_name}>{data.farmer_name}</Text>
</View>
<Text style={styles.timestamp}>{data.uploaded_time}</Text>
</View>
<View style={styles.cardbody}>
<Image style={styles.cardbody_image} source={{uri: product_image}}/>
<Text style={styles.p_name}>{data.product_name}</Text>
<Text style={styles.p_desc}>{data.product_description}</Text>
<View>
<TouchableOpacity
onPress={() => {
this.setModalVisible(true);
}} style={styles.buttonContainer}>
<Text style={styles.buttonText}>Show Modal</Text>
</TouchableOpacity>
</View>
</View>
</View>
)
});
return (
<View style={styles.container}>
<View elevation={5} style={styles.mainheader}>
<Text style={styles.iconTop} onPress={() => this.PostTimeline()}>
<Ionicons name="md-refresh" size={32} color="black" />
</Text>
<Text style={styles.headerTitle}>Home</Text>
<Text style={styles.iconTop} onPress={() => this.Home()}>
<Ionicons name="md-home" size={32} color="black" />
</Text>
</View>
<View style={styles.content}>
<View style={{padding: 10}}>
<Text style={styles.headerText}><Ionicons name="md-cart" size={26} color="black" /> Marketplace</Text>
</View>
<View style={{flex:1}}>
<ScrollView alwaysBounceVertical={true} contentContainerStyle={{ flexGrow: 1}} enabled bounces={true}>
{timeLineList}
</ScrollView>
</View>
</View>
</View>
);
}
And if there is a better way to refactor this code, I am open to learning. Thanks
I have quickly changed your code to give you the idea of how this could work checkout below this should work.
No need to loop the modal set the data to the state when button is pressed and modal can read the data from the state.
import React, {Component} from 'react';
import {TextInput,Modal,Alert,TouchableHighlight,StyleSheet,RefreshControl ,ScrollView,Dimensions,Image,StatusBar,ActivityIndicator,Text, View,TouchableOpacity,KeyboardAvoidingView} from 'react-native';
import { createBottomTabNavigator,createStackNavigator,createSwitchNavigator, createAppContainer} from "react-navigation";
let {height, width} = Dimensions.get('window');
import { Ionicons } from '#expo/vector-icons';
import { AsyncStorage } from 'react-native';
export default class Timeline extends Component {
constructor(props){
super(props)
console.log(props)
this.state = {
username: '',
photo: '',
email: '',
userId: '',
address: '',
timeline: [],
modalVisible: false,
refreshing: false,
selectedData: [],
}
}
setModalVisible(visible) {
this.setState({modalVisible: visible});
}
Home = () => {
alert("Home");
}
PostTimeline = () => {
return fetch( "http://texotrack.com/api/user/timeline.php", {
method: "POST",
headers:{
'Content-Type': 'application/json'
},
body: JSON.stringify({
action: 'fetch'
})
}).then((response) => response.json()).then((responseJsonFromServer) => {
this.setState({
timeline: responseJsonFromServer
});
})
}
componentDidMount(){
this.PostTimeline();
AsyncStorage.getItem("key").then((data) =>{
const val = JSON.parse(data);
this.setState({
username: data.name,
photo: data.photo,
email: data.email,
userId: data.id,
address: data.address
})
})
}
_selectedItem = (data) => {
this.setState({selectedData: data});
this.setModalVisible(true);
}
render() {
const data = this.state.selectedData
const timeLineList = this.state.timeline.map((data) => {
console.log(data);
const thumbnail = data.profile_img;
const product_image = data.product_image;
return (
<View elevation={5} key={data.id} style={styles.card}>
<View style={styles.cardheader}>
<View style={styles.miniheader}>
<Image style={styles.thumbnail} source={{uri: thumbnail}} />
<Text style={styles.thumb_name}>{data.farmer_name}</Text>
</View>
<Text style={styles.timestamp}>{data.uploaded_time}</Text>
</View>
<View style={styles.cardbody}>
<Image style={styles.cardbody_image} source={{uri: product_image}}/>
<Text style={styles.p_name}>{data.product_name}</Text>
<Text style={styles.p_desc}>{data.product_description}</Text>
<View>
<TouchableOpacity
onPress={() => {
this._selectedItem(data);
}} style={styles.buttonContainer}>
<Text style={styles.buttonText}>Show Modal</Text>
</TouchableOpacity>
</View>
</View>
</View>
)
});
return (
<View style={styles.container}>
<View elevation={5} style={styles.mainheader}>
<Text style={styles.iconTop} onPress={() => this.PostTimeline()}>
<Ionicons name="md-refresh" size={32} color="black" />
</Text>
<Text style={styles.headerTitle}>Home</Text>
<Text style={styles.iconTop} onPress={() => this.Home()}>
<Ionicons name="md-home" size={32} color="black" />
</Text>
</View>
<View style={styles.content}>
<View style={{padding: 10}}>
<Text style={styles.headerText}><Ionicons name="md-cart" size={26} color="black" /> Marketplace</Text>
</View>
<View style={{flex:1}}>
<ScrollView alwaysBounceVertical={true} contentContainerStyle={{ flexGrow: 1}} enabled bounces={true}>
{timeLineList}
</ScrollView>
</View>
</View>
<Modal
animationType="fade"
transparent={false}
visible={this.state.modalVisible}
key={data.id}
onRequestClose={() => {
alert('Modal has been closed.');
}}>
<View style={{margin: 10}}>
<Text style={styles.headerText}>Product details: {data.product_name}</Text>
<View style={styles.cardheader}>
<View style={styles.miniheader}>
<Image style={styles.thumbnail} source={{uri: data.thumbnail}} />
<Text style={styles.thumb_name}>{data.farmer_name}</Text>
</View>
<Text style={styles.timestamp}>{data.uploaded_time}</Text>
</View>
<View style={styles.cardbody}>
<Image style={styles.cardbody_image} source={{uri: data.product_image}}/>
<Text style={styles.p_name}>{data.product_name}</Text>
<Text style={styles.p_desc}>{data.product_description}</Text>
<View>
</View>
</View>
<TouchableHighlight
onPress={() => {
this.setModalVisible(!this.state.modalVisible);
}}>
<Text>Close</Text>
</TouchableHighlight>
</View>
</Modal>
</View>
);
}
}

Categories

Resources