Related
i have 2 functions
one is to get the value from a REST api and populate a picker (This is a success, as it works fine) now the second picker is supposed to get value from the first picker and then call another REST api and then populate from another REST api, but this one is a proven difficulty.
How can i get the value from the first picker and use it to call another REST api which would inturn populate the second picker.
PS here is what i am trying to achieve, i select the country like this
and it shows the corresponding banks in the country, but here it is not working this is what i have
My code is looking thus :
import {
ImageBackground,
Modal,
ScrollView,
StyleSheet,
Text,
TextInput,
TouchableOpacity,
View,
} from 'react-native';
import {Picker} from '#react-native-picker/picker';
import React, {useEffect, useState} from 'react';
import {useNavigation} from '#react-navigation/native';
import BackgroundOpacity from './BackgroundOpacity';
const InternationalPayments = () => {
const navigation = useNavigation();
const [getBanks, setGetBanks] = useState([]);
const [getCountry, setGetCountry] = useState([]);
const [bank_name, setBank_name] = useState('');
const [country_name, setCountry_name] = useState('');
const [country_symbol, setCountry_symbol] = useState('');
const [bank_code, setBank_code] = useState('');
const [selectedCountry, setSelectedCountry] = useState();
const [selectedBank, setSelectedBank] = useState();
const [modalVisible, setModalVisible] = useState(false);
getBanksByCountry = (symbol) =>{
fetch(`https://api.flutterwave.com/v3/banks/${symbol}`,{
method:'GET',
headers:{
'Content-type': 'application/json',
'Authorization': 'Bearer FLWSECK_TEST-72fe360edef17334f4817a17407011bb-X',
},
}).then(response = response.json())
.then(responseJson =>{
setGetBanks(responseJson.data);
setBank_name(responseJson.data.name);
setBank_code(responseJson.data.code);
})
}
getallCountry = async () =>{
fetch('https://webserver-migospay.onrender.com/api/location/get-country',{ //<=== This one is working fine, gets the countries without issues
method:'GET',
headers:{
'Content-type': 'application/json'
},
}).then(response => response.json())
.then(responseJson=>{
setGetCountry(responseJson.data);
setCountry_name(responseJson.data.country_name);
setCountry_symbol(responseJson.data.symbol);
//getBanksByCountry(country_symbol); //<== first place i used it, did not work
})
}
useEffect(()=>{
getallCountry();
})
return (
<View style={styles.container}>
<BackgroundOpacity
display={Platform.OS === 'ios' ? false : modalVisible}
/>
<View style={styles.space} />
<ScrollView
contentContainerStyle={{
justifyContent: 'space-between',
alignItems: 'center',
}}>
<ImageBackground
source={{
uri: 'asset:/logo/bg.JPG',
}}
imageStyle={{borderRadius: 6}}
style={{
top: -30,
paddingTop: 95,
alignSelf: 'center',
width: 328,
height: 115,
borderadius: 9,
justifyContent: 'center',
alignSelf: 'center',
alignItems: 'center',
}}>
<View>
<Text style={styles.accText}>Wallet Balance</Text>
<Text style={styles.text}> 250,000 </Text>
</View>
</ImageBackground>
<View
style={{
borderRadius: 5,
borderWidth: 1,
overflow: 'hidden',
height: 53,
padding: 0,
borderColor: '#00BB23',
}}>
{
<Picker
style={{
width: 300,
height: 55,
borderBottomWidth: 1,
}}
itemStyle={{
fontSize: 25,
fontFamily: 'Poppins-Medium',
}}
selectedValue={selectedCountry}
onValueChange={(value, index) => setSelectedCountry(value)}
>
<Picker.Item label="Select Country" />
{getCountry.map((country, index) => (
<Picker.Item label={country.country_name} value={country.symbol} key={index} /> //<== country name works fine without problems
))}
</Picker>
}
</View>
<View style={styles.space}/>
<View
style={{
borderRadius: 5,
borderWidth: 1,
overflow: 'hidden',
height: 53,
padding: 0,
borderColor: '#00BB23',
}}>
{
<Picker
style={{
width: 300,
height: 55,
borderBottomWidth: 1,
}}
itemStyle={{
fontSize: 25,
fontFamily: 'Poppins-Medium',
}}
selectedValue={selectedBank}
onValueChange={(value, index) => setSelectedBank(value)}
>
<Picker.Item label="Select Bank" />
{getBanks.map((bank, index) => (
<Picker.Item label={bank.name} value={bank.code} key={index} /> //<== Does not return bank name here
))}
</Picker>
}
</View>
<View style={styles.space2}/>
<TextInput
placeholder="Destination Account"
onChangeText={creditAccount => this.setState({creditAccount})}
style={styles.input}
/>
<TextInput
placeholder=" Amount"
onChangeText={amount => this.setState({amount})}
style={styles.input}
/>
<TextInput
placeholder=" Narration"
onChangeText={description => this.setState({description})}
style={styles.input}
/>
<TextInput
placeholder=" Destination Branch Code"
onChangeText={description => this.setState({description})}
style={styles.input}
/>
<TextInput
placeholder=" Beneficiary Name"
onChangeText={description => this.setState({description})}
style={styles.input}
/>
<View
style={{
borderRadius: 5,
borderWidth: 1,
overflow: 'hidden',
height: 35,
padding: 0,
top: 10,
borderColor: '#00BB23',
}}>
{
<Picker
style={{
width: 300,
height: 53,
borderBottomWidth: 1,
}}
itemStyle={{
fontSize: 25,
fontFamily: 'Poppins-Medium',
}}>
<Picker.Item label="Currency" value="accNum" />
<Picker.Item label="NGN" value="NGN" />
</Picker>
}
</View>
<TouchableOpacity
onPress={() => {
setModalVisible(true);
}}
style={styles.button}>
<Text style={styles.loginbtn}> Transfer </Text>
</TouchableOpacity>
<Modal
hasBackdrop={true}
backdropOpacity={0.2}
backdropColor="black"
transparent
visible={modalVisible}
onRequestClose={() => setModalVisible(false)}>
<View style={styles.modal}>
<Text>Hello From Modal</Text>
<TouchableOpacity>
<Text>Modal! Modal!</Text>
</TouchableOpacity>
</View>
</Modal>
</ScrollView>
</View>
);
};
export default InternationalPayments;
const styles = StyleSheet.create({
container: {
paddingTop: 40,
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between',
},
modal: {
top: '50%',
height: '50%',
backgroundColor: '#fff',
},
accText: {
top: -50,
paddingTop: 10,
justifyContent: 'center',
alignItems: 'center',
fontFamily: 'Poppins-Medium',
fontSize: 12,
color: 'white',
textAlign: 'center',
},
text: {
top: -50,
fontSize: 20,
color: 'white',
textAlign: 'center',
fontFamily: 'Poppins-Bold',
},
input: {
top: 10,
width: 300,
height: 53,
margin: 10,
fontSize: 12,
borderColor: '#00BB23',
fontFamily: 'Poppins-Bold',
borderRadius: 5,
borderWidth: 1,
marginBottom: 30,
},
button: {
marginTop: 40,
width: 150,
height: 50,
padding: 10,
borderRadius: 10,
backgroundColor: '#00BB23',
alignItems: 'center',
},
Regbutton: {
width: 150,
height: 52,
padding: 10,
borderRadius: 10,
backgroundColor: '#ffffff',
alignItems: 'center',
borderWidth: 2,
borderColor: '#030303',
},
loginbtn: {
color: '#ffff',
fontSize: 15,
fontFamily: 'Poppins-Medium',
},
AccountBalance: {
fontSize: 13,
fontWeight: 'bold',
textAlign: 'left',
},
loginbtn2: {
color: '#030303',
fontSize: 20,
fontWeight: 'bold',
},
logo: {
width: 150,
height: 150,
},
space: {
top: 10,
width: 10,
height: 20,
},
space2: {
width: 10,
height: 10,
},
imageStyle: {
flexDirection: 'row',
justifyContent: 'center',
padding: 5,
margin: 2,
height: 15,
width: 15,
resizeMode: 'stretch',
marginBottom: 8,
marginTop: 8,
alignItems: 'center',
},
});
What must I do in this case? its not returning anything to the second Picker
call getBanksByCountry function inside useEffect with selectedCountry as dependency (since you want to fetch the banks each time the country changes)
useEffect(()=>{
getBanksByCountry(selectedCountry.symbol)
},[selectedCountry])
After very intense struggle, i got it to work.
So here is what i Did
On the picker , i formally made it like so
<Picker
style={{
width: 300,
height: 55,
borderBottomWidth: 1,
}}
itemStyle={{
fontSize: 25,
fontFamily: 'Poppins-Medium',
}}
selectedValue={selectedCountry}
onValueChange={(value, index) => [
setSelectedCountry(value),
getBanksByCountry(value), //<== I added the function to the picker vis Onchange since that is the function that handles the selection and all.
]}>
<Picker.Item label="Select Country" />
{getCountry.map((country, index) => (
<Picker.Item
label={country.country_name}
value={country.symbol}
key={index}
/>
))}
</Picker>
Next i made the getBanksByCountry(symbol) function to look like this
getBanksByCountry = async (symbol) => {
if (symbol === 'GH') {
fetch('https://api.flutterwave.com/v3/banks/GH', {
method: 'GET',
headers: {
'Content-type': 'application/json',
'Authorization':
'Bearer FLWSECK_TEST-72fe360edef17334f4817a17407011bb-X',
},
})
.then(response => response.json())
.then(async responseJson => {
setGetBanks(responseJson.data);
setBank_name(responseJson.data.name);
setBank_code(responseJson.data.code);
});
} if (symbol === 'UG') {
fetch('https://api.flutterwave.com/v3/banks/UG', {
method: 'GET',
headers: {
'Content-type': 'application/json',
'Authorization':
'Bearer FLWSECK_TEST-72fe360edef17334f4817a17407011bb-X',
},
})
.then(response => response.json())
.then(async responseJson => {
setGetBanks(responseJson.data);
setBank_name(responseJson.data.name);
setBank_code(responseJson.data.code);
});
}
if (symbol === 'ZA') {
fetch('https://api.flutterwave.com/v3/banks/ZA', {
method: 'GET',
headers: {
'Content-type': 'application/json',
'Authorization':
'Bearer FLWSECK_TEST-72fe360edef17334f4817a17407011bb-X',
},
})
.then(response => response.json())
.then(async responseJson => {
setGetBanks(responseJson.data);
setBank_name(responseJson.data.name);
setBank_code(responseJson.data.code);
});
} if (symbol === 'TZ') {
fetch('https://api.flutterwave.com/v3/banks/TZ', {
method: 'GET',
headers: {
'Content-type': 'application/json',
'Authorization':
'Bearer FLWSECK_TEST-72fe360edef17334f4817a17407011bb-X',
},
})
.then(response => response.json())
.then(async responseJson => {
setGetBanks(responseJson.data);
setBank_name(responseJson.data.name);
setBank_code(responseJson.data.code);
});
}
};
Which in turn selects the country, so i just need to update my own REST api and have it communicate directly with the end servers and it gives me the required results :)
Hopefully this would be useful for someone someday :)
My React Native Flatlist is not rendering. It does not show any error nor does the app crash. It just shows an ActivityIndicator
home.js
export default function Second({navigation}) {
const [loca, setLoca] = useState([]);
const Get = async () => {
const myDoc = collection(db, 'users');
const querySnapshot = await getDocs(myDoc);
querySnapshot.forEach(doc => {
console.log(doc.id, ' => ', doc.data());
setLoca({
id: doc.id,
fname: doc.data().fname,
});
console.log(loca);
});
};
const Logout = () => {
signOut(auth)
.then(() => {
// Sign-out successful.
console.log('log out');
navigation.navigate('Login');
})
.catch(error => {
// An error happened.
console.log(error);
});
};
useEffect(() => {
Get();
}, []);
const renderItemm = ({item}) => <Comp title={item.fname} />;
return (
<View style={styles.conn}>
<ImageBackground source={image} resizeMode="cover" style={{flex: 1}}>
<View style={{paddingHorizontal: 15}}>
<View style={styles.box}>
<View style={{justifyContent: 'space-between'}}>
<Text>HOME</Text>
<TouchableOpacity style={styles.box1} onPress={Logout}>
<Text>dd</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.box1}
onPress={() => navigation.navigate('Third')}></TouchableOpacity>
</View>
</View>
{loca.length > 0 ? (
<FlatList
data={loca}
renderItem={renderItemm}
keyExtractor={item => item.id}
/>
) : (
<ActivityIndicator />
)}
</View>
</ImageBackground>
</View>
);
}
const styles = StyleSheet.create({
conn: {
//flexDirection: 'column',
flex: 1,
},
tt: {
color: 'white',
backgroundColor: '#4DA69B',
fontSize: 24,
width: 80,
height: 80,
borderRadius: 40,
alignItems: 'center',
},
box: {
marginTop: 10,
flexWrap: 'wrap',
flexDirection: 'row',
},
end: {
//justifyContent: 'space-between',
alignItems: 'flex-end',
marginBottom: 10,
},
box1: {
width: 48,
height: 48,
borderRadius: 24,
backgroundColor: '#67BE92',
marginTop: 10,
marginLeft: 10,
alignItems: 'flex-end',
},
boxxx: {
backgroundColor: '#f9c2ff',
padding: 20,
marginVertical: 8,
marginHorizontal: 16,
},
});
comp.js
const comp = (props) => {
return (
<View style={styles.conn}>
<View style={styles.box}>
<Text>{props.title}</Text>
</View>
</View>
);
};
export default comp;
const styles = StyleSheet.create({
conn: {
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between',
},
tt: {
color: 'white',
backgroundColor: '#4DA69B',
fontSize: 24,
width: 80,
height: 80,
borderRadius: 40,
alignItems: 'center',
},
box: {
flex: 1,
marginTop: 10,
borderRadius: 10,
width: '100%',
height: 115,
borderWidth: 1,
borderColor: '#67BE92',
backgroundColor: 'white',
flexDirection: 'row',
},
end: {
alignItems: 'flex-end',
marginBottom: 10,
},
box1: {
width: 48,
height: 48,
borderRadius: 24,
backgroundColor: '#67BE92',
marginTop: 10,
marginLeft: 10,
},
});
i dont slove this plobem it show ActivityIndicator not show flatlist I use my firebase data and console.lod(loca) show that data but flatlist not show
solve my flatlist and show in my project
The data passed to the FlatList should always be an array. So you should edit your code as follow:
const Get = async () => {
const myDoc = collection(db, 'users');
const querySnapshot = await getDocs(myDoc);
querySnapshot.forEach(doc => {
console.log(doc.id, ' => ', doc.data());
// I changed the below
setLoca([...loca, {
id: doc.id,
fname: doc.data().fname,
}]);
console.log(loca);
});
};
We are looping over querySnapshot, so this syntax "setLoca([...loca, {..}])" keeps the already saved data while looping.
In my app you can join a group. There are storys and messages. If there is no story or messages modal is open fast. But If I have 30 text messages to render and want to click to open my modal then it takes 1-2 seconds or later to open. The same issue if I click a button. The opacity and function works until 1-2 seconds but if there is no much messages to render then it goes fast. I need help.
message render function
<FlatList
data={globalMessages}
style={{width: '100%'}}
contentContainerStyle={{marginLeft: 12}}
renderItem={({ item }) => (
<TouchableOpacity onLongPress={() => deleteMessage(item.id)} style={{width: 230, flexDirection: 'column', backgroundColor: '#eee', padding: 8, borderRadius: 12, margin: 12, marginLeft: 0, marginTop: 0}}>
<Text style={{fontFamily: 'poppins-light', fontSize: 16, color: '#333'}}>{item.message}</Text>
<Text style={{fontFamily: 'poppins-medium', fontSize: 12, color: '#333'}}>{item.date}</Text>
</TouchableOpacity>
)}
keyExtractor={item => item.id.toString()}
// ListHeaderComponent={() => this.renderHeader()}
horizontal={false}
nestedScrollEnabled
showsHorizontalScrollIndicator={false}
// Performance settings
removeClippedSubviews={true} // Unmount components when outside of window
initialNumToRender={2} // Reduce initial render amount
maxToRenderPerBatch={1} // Reduce number in each render batch
updateCellsBatchingPeriod={100} // Increase time between renders
windowSize={4} // Reduce the window size
/>
fullCode:
import { StatusBar } from 'expo-status-bar';
import React, { useState, useEffect, useRef } from 'react';
import { StyleSheet, Text, TextInput, View, TouchableOpacity, Image, Dimensions, ImageBackground, ActivityIndicator, ScrollView, FlatList, TouchableWithoutFeedback } from 'react-native';
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
import { AntDesign, Ionicons } from '#expo/vector-icons';
import Modal from 'react-native-modal';
import * as ImagePicker from 'expo-image-picker';
import uploadStoryAPI from '../api/uploadStory';
import createMessageAPI from '../api/createMessage';
import io from 'socket.io-client/dist/socket.io';
const width = Dimensions.get('window').width;
const height = Dimensions.get('window').height;
const Room = ({ route }) => {
const socket = io('http://192.168.0.249:3000', {
transports: ['websocket']
});
const [connected, setConnected] = useState(false);
const [areaHeight, setAreaHeight] = useState(0);
const [chatMessage, setChatMessage] = useState('');
const [globalMessages, setGlobalMessages] = useState(route.params.messages || []);
const [loadSendChatMessage, setLoadSendChatMessage] = useState(false);
const [alignItem, setAlignItem] = useState('center');
const [addStory, setAddStory] = useState(false);
const [storys, setStorys] = useState(route.params.storys || []);
const [modalImagePreview, setModalImagePreview] = useState(false);
const [modalDeleteMessage, setModalDeleteMessage] = useState(false);
const [imagePreview, setImagePreview] = useState('');
const [loadUpload, setLoadUpload] = useState(false);
const [sourceStory, setSourceStory] = useState({
uri: null,
type: null,
name: null
});
useEffect(() => {
socket.on('connect', () => {
setConnected(true);
console.log('user connected');
});
socket.on('getmessage', message => {
globalMessages.length > 0 ?
setGlobalMessages(prevState => {
return [...prevState, message]
}) : setGlobalMessages([message]);
handleAddMessage();
});
});
const handleAlign = () => {
areaHeight > 100 ? setAlignItem('flex-end') : setAlignItem('center');
}
const handleAddStory = async () => {
try {
let result = await ImagePicker.launchImageLibraryAsync({
allowsEditing: true,
aspect: [1, 1]
});
setAddStory(false);
if(result.cancelled) {
setAddStory(false);
return;
}
let localUri = result.uri;
let filename = localUri.split('/').pop();
// Infer the type of the image
let match = /\.(\w+)$/.exec(filename);
let type = match ? `image/${match[1]}` : `image`;
setImagePreview(localUri);
setSourceStory({
uri: localUri,
type,
filename
});
setModalImagePreview(true);
} catch(e) {
return;
}
};
const handleUploadToServer = async () => {
try {
setLoadUpload(true);
let res = await uploadStoryAPI(route.params.roomID, sourceStory);
res.upload && storys.length > 0
? setStorys(prevState => {
return [{
source: res.source
}, ...prevState]
}) : setStorys([{ source: res.source}]);
console.log(`D ${storys}`)
res.upload ? (setLoadUpload(false),setModalImagePreview(false)) : setLoadUpload(false);
} catch(e) {
return e;
}
};
const handleAddMessage = async () => {
try {
setLoadSendChatMessage(true);
const res = await createMessageAPI(route.params.roomID, chatMessage);
console.log(res);
//scrollViewRef.current.scrollToEnd({animated: true});
setLoadSendChatMessage(false);
} catch(e) {
console.log(e);
return e;
}
};
const deleteMessage = async id => {
try {
console.log(id);
} catch(e) {
return e;
}
};
return (
<KeyboardAwareScrollView keyboardShouldPersistTaps="handled" style={{margin: 0, padding: 0}}>
<View style={{height: height - 155, backgroundColor: '#fff'}}>
<View>
<ScrollView>
<Text style={styles.title}>Storys</Text>
{
storys.length > 0
?
<FlatList
data={storys}
contentContainerStyle={{marginLeft: 8}}
renderItem={({ item }) => (
<TouchableOpacity key={`index-${item.source}`} style={{padding: 0, marginRight: 16, borderWidth: 2, justifyContent: 'center', alignItems: 'center', borderRadius: 100, borderColor: '#1ab7ff', height: 68, width: 68}}>
<Image resizeMode="contain" source={{uri: `http://192.168.0.249:3000/build/${item.source}`}} style={{height: 55, width: 55, borderRadius: 500}} />
</TouchableOpacity>
)}
keyExtractor={item => item.source.toString()}
// ListHeaderComponent={() => this.renderHeader()}
nestedScrollEnabled
horizontal
showsHorizontalScrollIndicator={false}
// Performance settings
removeClippedSubviews={true} // Unmount components when outside of window
initialNumToRender={2} // Reduce initial render amount
maxToRenderPerBatch={1} // Reduce number in each render batch
updateCellsBatchingPeriod={100} // Increase time between renders
windowSize={7} // Reduce the window size
/>
:
<Text>Es sind zurzeit keine Storys vorhanden.</Text>
}
<Text style={styles.title}>Nachrichten</Text>
{
globalMessages.length > 0
?
<FlatList
data={globalMessages}
style={{width: '100%'}}
contentContainerStyle={{marginLeft: 12}}
renderItem={({ item }) => (
<TouchableOpacity onLongPress={() => deleteMessage(item.id)} style={{width: 230, flexDirection: 'column', backgroundColor: '#eee', padding: 8, borderRadius: 12, margin: 12, marginLeft: 0, marginTop: 0}}>
<Text style={{fontFamily: 'poppins-light', fontSize: 16, color: '#333'}}>{item.message}</Text>
<Text style={{fontFamily: 'poppins-medium', fontSize: 12, color: '#333'}}>{item.date}</Text>
</TouchableOpacity>
)}
keyExtractor={item => item.id.toString()}
// ListHeaderComponent={() => this.renderHeader()}
horizontal={false}
nestedScrollEnabled
showsHorizontalScrollIndicator={false}
// Performance settings
removeClippedSubviews={true} // Unmount components when outside of window
initialNumToRender={2} // Reduce initial render amount
maxToRenderPerBatch={1} // Reduce number in each render batch
updateCellsBatchingPeriod={100} // Increase time between renders
windowSize={4} // Reduce the window size
/>
: null
}
</ScrollView>
</View>
</View>
<View style={{flex: 1, paddingLeft: 16, paddingTop: 8, paddingRight: 16, paddingBottom: 12, backgroundColor: '#fff', alignItems: alignItem, justifyContent:'space-between', flexDirection: 'row'}}>
<TouchableOpacity onPress={() => setAddStory(true)}>
<AntDesign name="pluscircleo" size={32} color="#444" />
</TouchableOpacity>
<TextInput
onChangeText={e => setChatMessage(e)}
// onFocus={() => setAlignItem('flex-end')}
onEndEditing={() => handleAlign()}
value={chatMessage}
multiline={true}
style={[styles.input, {height: Math.max(50, areaHeight)}]}
onContentSizeChange={e => {
setAreaHeight(e.nativeEvent.contentSize.height);
}}
placeholder="Gebe eine Nachricht ein..." />
<TouchableOpacity onPress={() => chatMessage.length > 0 ? socket.emit('getmessage', {
chatMessage,
date: Date.now()
}) : null} style={{padding: 8, paddingRight: 10, borderRadius: 8, backgroundColor: '#1ab7ff'}}>
{ !loadSendChatMessage ? <Ionicons name="paper-plane-outline" size={28} color="#fff" /> : <ActivityIndicator style={{height: 20, width: 20}} color="#fff" />}
</TouchableOpacity>
</View>
{ /* Ask user if he wants to upload */}
<Modal
isVisible={modalImagePreview}
swipeDirection="down"
onSwipeComplete={() => setModalImagePreview(false)}
onBackButtonPress={() => setModalImagePreview(false)}
onBackdropPress={() => setModalImagePreview(false)}
backdropTransitionOutTiming={0}
// style={{margin: 0, padding: 0}}
>
<View style={{ backgroundColor: '#fff', borderRadius: 12, padding: 12}}>
<Text style={{fontFamily: 'poppins-light', color: '#333', fontSize: 18, textAlign: 'center', marginBottom: 10}}>Möchtest du diese Story hochladen?</Text>
{ <Image resizeMode="contain" style={{height: 250, borderRadius: 12}} source={{uri: imagePreview}} /> }
<View style={{flexDirection: 'row', justifyContent: 'space-around', alignItems: 'center', marginTop: 20, marginBottom: 10}}>
<TouchableOpacity onPress={() => setModalImagePreview(false)}>
<Text style={{fontFamily: 'poppins-light', color: '#333', borderWidth: 1, borderColor: '#eee', padding: 10, paddingTop: 13, borderRadius: 8}}>Abbrechen</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => handleUploadToServer()} style={{backgroundColor: '#1ab7ff', padding: 10, paddingTop: 13, borderRadius: 8}}>
{ !loadUpload ? <Text style={{fontFamily: 'poppins-light', color: '#fff'}}>Story hinzufügen</Text> : <ActivityIndicator style={{height: 20, width: 20}} color="#fff" /> }
</TouchableOpacity>
</View>
</View>
</Modal>
{ /* Modal open Story */ }
<Modal
isVisible={addStory}
swipeDirection="down"
onSwipeComplete={() => setAddStory(false)}
onBackButtonPress={() => setAddStory(false)}
onBackdropPress={() => setAddStory(false)}
backdropTransitionOutTiming={0}
style={{margin: 0, padding: 0}}
>
<View style={{position: 'absolute', bottom: 0, backgroundColor: '#fff', width: '100%', justifyContent: 'center', alignItems: 'center', borderTopLeftRadius: 20, borderTopRightRadius: 20}}>
<TouchableOpacity onPress={() => handleAddStory()} style={{padding: 20, backgroundColor: '#1ab7ff', width: width, justifyContent: 'center', alignItems: 'center',borderTopLeftRadius: 20, borderTopRightRadius: 20}}>
<Text style={{color: '#fff', fontFamily: 'poppins-light'}}>Story hinzufügen</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => setAddStory(false)} style={{padding: 20}}>
<Text>Abbrechen</Text>
</TouchableOpacity>
</View>
</Modal>
</KeyboardAwareScrollView>
)
};
I am able to create the dynamic checkbox but i need to check and uncheck it separately, right now if i check one everything gets checked and if i uncheck everything gets unchecked.
How to change the value of checkbox separately for each checkbox from state?
import React from 'react';
import {View,Text,StyleSheet,TouchableOpacity,Image,Switch,Platform,Dimensions,PixelRatio,} from'react-native';
import ImagePicker from 'react-native-image-picker';
import { Input, Button } from 'react-native-elements';
import { moderateScale } from 'react-native-size-matters';
const deviceWidth = Dimensions.get('window').width;
const deviceHeight = Dimensions.get('window').height;
const calcHeight = x => PixelRatio.roundToNearestPixel((deviceHeight * x) / 100);
const calcWidth = x => PixelRatio.roundToNearestPixel((deviceWidth * x) / 100);
class ErrorScreen extends React.Component {
constructor() {
super();
this.state = {
arr: [],
parkPay: false,
itemChecked: false,
index: null,
};
}
functionTwo = () => {
alert('func 2');
this.setState(() => ({
parkPay: true,
}));
};
checkedItem = index => {
console.log('this is index', index);
// let itemChecked = this.state.itemChecked
if (this.state.index != index) {
this.setState(() => ({
index: index,
itemChecked: !this.state.itemChecked,
}));
}
};
addParkField = () => {
console.log('jjjjj');
console.log(' ^^ props in parking form ^^ ', this.props);
let x = 0;
this.setState(() => ({
arr: [...this.state.arr, ''],
}));
// this.addFieldSecond()
// this.props.addParkFieldSecond()
};
render() {
return (
<View>
<View
style={{flex: 1, paddingRight: calcWidth(4),paddingLeft: calcWidth(6), paddingTop: calcHeight(4),paddingBottom: calcHeight(4),
}}>
<Input
placeholder="Enter Amount"
label="Enter Amount"
labelStyle={{ fontWeight: '200', color: 'black' }}
inputContainerStyle={{
paddingRight: calcWidth(2),
paddingLeft: calcWidth(2),
paddingTop: calcHeight(1),
paddingBottom: calcHeight(1),
}}
// onChangeText={this.props.parkingAmount}
/>
<Text style={[styles.error]}>{this.state.errors.Amount}</Text>
<View
style={{ paddingLeft: calcWidth(2), paddingTop: calcHeight(4) }}>
<View style={{ paddingRight: calcWidth(70) }}>
<Switch
value={this.state.parkPay}
style={
Platform.OS === 'ios' ? styles.switchIOS : styles.switchAND
}
// onValueChange={(value) => {this.props.toggleCustomerParkingPay(value); this.functionTwo()}}
/>
</View>
<Text style={{ paddingTop: calcHeight(8) }}>Paid By Customer</Text>
</View>
</View>
<View style={{}}>
{this.state.arr.map((extra, index) => {
return (
<View
style={{
flex: 1,
paddingRight: calcWidth(4),
paddingLeft: calcWidth(20),
paddingTop: calcHeight(15),
paddingBottom: calcHeight(4),
}}
key={index}>
<Input
placeholder="Enter Amount"
label="Enter Amount"
labelStyle={{ fontWeight: '200', color: 'black' }}
inputContainerStyle={{
paddingRight: calcWidth(2),
paddingLeft: calcWidth(2),
paddingTop: calcHeight(1),
paddingBottom: calcHeight(1),
}}
// onChangeText={this.handleAmount}
// onChangeText={this.props.parkingAmount}
/>
<Text style={[styles.error]}>{this.state.errors.Amount}</Text>
<View style={{ paddingTop: calcHeight(4) }}>
<View style={{ paddingRight: calcWidth(70) }}>
<Switch
value={this.state.parkPay}
style={
Platform.OS === 'ios'
? styles.switchIOS
: styles.switchAND
}
// onValueChange={(value) => {this.props.toggleCustomerParkingPay(value);}}
/>
</View>
<Text style={{ paddingTop: calcHeight(8) }}>
Paid By Customer
</Text>
</View>
</View>
);
})}
<View>
<View
style={{ paddingLeft: calcWidth(60), paddingTop: calcHeight(2) }}>
<TouchableOpacity
style={[styles.cardCirclePassenger]}
onPress={this.addParkField}>
<View
style={{
justifyContent: 'center',
alignItems: 'center',
paddingTop: calcHeight(2.2),
}}>
{/* <Image
style={{width: 24, height: 24}}
source={require('../../images/Group424.png')}
/> */}
<Text>Add</Text>
</View>
</TouchableOpacity>
</View>
</View>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
cardCirclePassenger: {
backgroundColor: '#31588A',
marginBottom: 10,
marginLeft: '5%',
width: 60,
height: 60,
borderRadius: 60 / 2,
borderColor: 'white',
shadowOpacity: 0.2,
shadowRadius: 1,
shadowOffset: {
width: 3,
height: 3,
},
borderWidth: 1,
},
switchIOS: {
transform: [
{ scaleX: moderateScale(0.7, 0.2) },
{ scaleY: moderateScale(0.7, 0.2) },
],
},
switchAND: {
transform: [
{ scaleX: moderateScale(1, 0.2) },
{ scaleY: moderateScale(1, 0.2) },
],
},
});
export default ErrorScreen;
i worked around a little bit and found the below way to generate dynamic checboxes along with separate state values. hope this helps someone.
The below code creates dynamic key-value pairs in state. if you console.log the state in your render you'll see (check0:true check1:true check2: false ....) .
<Switch
value={this.state[`check${key}`]}
onValueChange={value => this.setState({ [`check${key}`]: value })}
/>
I have a component Logitem.js which has a DatePickerIOS component.
The component works as expected but for some reason the datepicker component's layout is messed up as shown below.
Ideally the datepicker component should be on top followed by the two buttons (with adequate space between datepicker component and the buttons)
Logitem.js code
import React, { Component } from 'react';
import { Text, View, Modal, DatePickerIOS, TextInput, TouchableHighlight } from 'react-native';
export default class Logitem extends Component {
state = {
//selecteddate: '1',
selectedweight: this.props.weight,
showmodal: false,
selecteddate: new Date(86400000 * this.props.logdate),
}
componentDidMount() {
console.log('State ==> '+this.state.selecteddate+' Logstring date ==> '+this.props.logstringdate);
}
deleteSelectedRecord(){
this.setState({ showmodal: false });
this.props.invokedelete(this.state.selecteddate);
}
saveSelectedRecord(){
this.setState({ showmodal: false });
this.props.invokesave(this.state.selecteddate, this.state.selectedweight);
}
onWeightClick = () => {
this.setState({ showmodal: true }, () => {
});
}
onDateChange(date) {
this.setState({
selecteddate: date
});
}
render() {
return (
<View style={styles.containerStyle}>
<Modal
animationType="slide"
transparent={false}
visible={this.state.showmodal}
onRequestClose={() => { alert("Modal has been closed.") }}
>
<View style={{ marginTop: 22 }}>
<DatePickerIOS
date={this.state.selecteddate}
mode="date"
onDateChange={(date) => this.onDateChange(date)}
style={{ height: 100, width: 300 }}
/>
</View>
<View style={{ marginTop: 22, borderColor: '#ddd', borderWidth: 5 }}>
<TextInput
returnKeyType="done"
keyboardType='numeric'
style={{
height: 40,
width: 60,
borderColor: 'gray',
borderWidth: 1,
}}
onChangeText={(text) => this.setState({ selectedweight: text })}
value={this.state.selectedweight.toString()}
/>
<Text>KG</Text>
<TouchableHighlight style={styles.buttonstyle} onPress={this.deleteSelectedRecord.bind(this)}>
<Text style={styles.buttontextstyle}>Delete</Text>
</TouchableHighlight>
<TouchableHighlight style={styles.buttonstyle} onPress={this.saveSelectedRecord.bind(this)}>
<Text style={styles.buttontextstyle}>Save</Text>
</TouchableHighlight>
</View>
</Modal>
<View style={styles.headerContentStyle}>
<Text>{this.props.logstringdate}</Text>
<Text>{this.props.bmi}</Text>
</View>
<View style={styles.thumbnailContainerStyle}>
<Text onPress={this.onWeightClick}>{this.props.weight}</Text>
</View>
</View>
);
}
};
const styles = {
containerStyle: {
borderWidth: 1,
borderRadius: 2,
borderColor: '#ddd',
borderBottomWidth: 1,
//shadowColor: '#000',
//shadowOffset: { width: 0, height: 2},
//shadowOpacity: 0.1,
//shadowRadius: 2,
//elevation: 1,
marginLeft: 5,
marginRight: 5,
marginTop:10,
},
thumbnailContainerStyle: {
justifyContent: 'center',
alignItems: 'center',
marginLeft: 10,
marginRight: 10,
flexDirection: 'row'
},
headerContentStyle: {
flexDirection: 'column',
justifyContent: 'space-around'
},
buttonstyle: {
marginRight: 40,
marginLeft: 40,
marginTop: 10,
paddingTop: 20,
paddingBottom: 20,
backgroundColor: '#68a0cf',
borderRadius: 10,
borderWidth: 1,
borderColor: '#fff'
},
buttontextstyle: {
color: '#fff',
textAlign: 'center',
}
};