How can I Get value from first picker and populate second picker? - react-native

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 :)

Related

How to put the Value gotten from a REST api to inputbox in React native?

I want to get the value of something from a REST api and display in a Textbox in React native. So far i am not getting it to the textbox and secondly it returns this Error
My source Code is looking thus
import { Button, Image, ImageBackground, StyleSheet, Text, TextInput, TouchableOpacity, View } from 'react-native'
import React, { useEffect, useState } from 'react';
import AsyncStorage from '#react-native-async-storage/async-storage';
import { Icon } from '#rneui/base'
const VirtualAccount = () => {
const [virtualAcc, setvirtualAcc] = useState();
const [account_number, setAccount_number] = useState("");
const [bank_name, setBank_name] = useState("");
sayAlert = () =>{
alert('Text copy button is active');
}
getVirtualAccount = async () => {
let token = await AsyncStorage.getItem('token');
let email = await AsyncStorage.getItem('email');
fetch(
'https://webserver-migospay.onrender.com/api/user-serv/get-virtual-account/'+email,
{
method: 'GET',
headers: {
'Content-type': 'application/json',
Authorization: `Bearer ${token}`,
},
},
)
.then(response => response.json())
.then(responseJson => {
setvirtualAcc(responseJson);
});
};
useEffect(() => {
//showdata();
getVirtualAccount();
});
return (
<View style={{top:30}}>
<ImageBackground
source={{
uri: 'asset:/logo/bg.JPG',
}}
imageStyle={{borderRadius: 6}}
style={{
top:15,
paddingTop:95,
alignSelf:'center',
width: 328,
height: 145,
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>
<Text
style={{
fontFamily: 'Poppins-Bold',
flexDirection: 'row',
paddingTop:55,
fontSize: 15,
left: 25,
color: 'gray',
}}>
Your Virtual Account
</Text>
<View>
<View style={{flexDirection:'row', alignSelf:'center',justifyContent:'center'}}>
<TextInput
placeholder=" Bank Name"
onChangeText={text => setBank_name(text)}
value={virtualAcc.bank_name}
style={styles.input}
/>
<TouchableOpacity onPress={()=>sayAlert()}>
<Image source={{uri:'asset:/logo/copy-image2.png'}} style={{height:30,width:30,left:-40, top:20}}/>
</TouchableOpacity>
</View>
<View style={{flexDirection:'row',alignSelf:'center',justifyContent:'center'}}>
<TextInput
placeholder=" Account Number"
onChangeText={text => setAccount_number(text)}
value={virtualAcc.account_number}
style={styles.input}
/>
<TouchableOpacity onPress={()=>sayAlert()}>
<Image source={{uri:'asset:/logo/copy-image2.png'}} style={{height:30,alignSelf:'center',width:30,left:-40, top:20}}/>
</TouchableOpacity>
</View>
</View>
</View>
</View>
)
}
export default VirtualAccount
const styles = StyleSheet.create({
shadowProp:{
shadowOffset: {width: -2, height: 4},
shadowColor: '#171717',
shadowOpacity: 0.2,
shadowRadius: 3,
},
container: {
flex: 1,
justifyContent: 'center',
padding: 20,
},
date_ofTransaction: {
marginTop: 20,
alignItems:'flex-start',
alignItems:'center',
left: -75,
fontFamily: 'Poppins-Light',
fontSize:9
},
paragraph: {
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
padding: 20,
},
text: {
top: -85,
fontSize: 30,
color: 'white',
textAlign: 'center',
fontFamily: 'Poppins-Bold',
},
mainContainer: {
paddingTop: 90,
justifyContent: 'center',
alignItems: 'center',
},
accText: {
top: -85,
paddingTop: 10,
justifyContent: 'center',
alignItems: 'center',
fontFamily: 'Poppins-Medium',
color: 'white',
textAlign: 'center',
},
PayeeName: {
justifyContent: 'flex-start',
alignItems:'center',
left: 23,
fontFamily: 'Poppins-Medium',
size: 800,
fontWeight:'bold'
},
amountValue: {
alignSelf:'flex-end',
top : -30,
right: -25,
fontFamily: 'Poppins-Medium',
size: 800,
fontWeight:'bold'
},
input:{
width:300,
height:55,
margin:10,
fontFamily : 'Poppins-Medium',
fontSize : 15,
borderBottomColor:'#00BB23',
borderBottomWidth: 1,
marginBottom: 30
},
})
Checked all over the internet, I could not find something valuable. or what exactly must I do? Does it appear to be something I am missing?
Edits
Please see the data it gets back from JSon
[
{
"_id": "63a21a3d3b6777ba42d0f0db",
"email": "john_kross2#yopmail.com",
"account_number": "0123456789",
"bank_name": "WEMA BANK",
"created_at": "2022-12-20T20:05:19.491Z",
"__v": 0
}
]
you are getting array as response thats why you are getting an error, try this code
fetch("https://webserver-migospay.onrender.com/api/userserv/getvirtualaccount/" +email,
{
method: "GET",
headers: {
"Content-type": "application/json",
Authorization: `Bearer ${token}`,
},
}
).then((response) => validateResponse(response));
const validateResponse = async (response) => {
var data = await response.json();
if (response.status === 200) {
setvirtualAcc(data[0]);
}
};
==> Simply Add this line in you fetch function.
.then(responseJson => {
setBank_name(responseJson.bank_name)
setvirtualAcc(responseJson);
});
==> Update the TextInput Code.
value={bank_name}

Styling problems How do I style this?

I have this as a worry
this is what the app home page looks like
some things are not aligned the way i want it to be, and its not nice. I am trying to get the date beneath the narration with a much smaller text and move the avatar somewhat beneath the recent transactions.
How do i align it properly
My source code is looking thus
import React, {useEffect, useState} from 'react';
import {
ActivityIndicator,
Button,
Image,
ImageBackground,
SafeAreaView,
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
import {Header, Avatar, Icon, Card} from '#rneui/themed';
import {FlatList, ScrollView} from 'react-native-gesture-handler';
import {useNavigation} from '#react-navigation/native';
import {Tab} from '#rneui/base';
import AsyncStorage from '#react-native-async-storage/async-storage';
import TextAvatar from 'react-native-text-avatar';
const HomePage = () => {
const [transaction_details, setTransaction_details] = useState([]);
const [isLoading, setLoading] = useState(true);
const navigation = useNavigation();
const Item = ({title}) => (
<View style={styles.item}>
<Text style={styles.title}>{title}</Text>
</View>
);
FlatListItemSeparator = () => {
return (
<View
style={{
height: 1,
left: 21,
width: 350,
backgroundColor: '#D3D3D3',
}}
/>
);
};
showdata = async () => {
let token = await AsyncStorage.getItem('token');
alert(token);
};
getTransactionsList = async () => {
let token = await AsyncStorage.getItem('token');
let email = await AsyncStorage.getItem('email');
fetch(
'https://webserver-migospay.onrender.com/api/user-data/get-transactionby-email/' +
email,
{
method: 'GET',
headers: {
'Content-type': 'application/json',
Authorization: `Bearer ${token}`,
},
},
)
.then(response => response.json())
.then(responseJson => {
setTransaction_details(responseJson);
setLoading(false);
});
};
useEffect(() => {
//showdata();
getTransactionsList();
});
/*useEffect(() => {
fetch('https://brotherlike-navies.000webhostapp.com/people/people.php', {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-type': 'application/json',
},
})
.then(response => response.json())
.then(responseJson => {
setTransaction_details(responseJson);
setLoading(false);
});
}, []);
*/
return (
<View style={{flex: 1}}>
<Header
containerStyle={{
backgroundColor: 'transparent',
justifyContent: 'space-around',
}}
leftComponent={
<Avatar
small
rounded
source={{
uri: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSiRne6FGeaSVKarmINpum5kCuJ-pwRiA9ZT6D4_TTnUVACpNbzwJKBMNdiicFDChdFuYA&usqp=CAU',
}}
onPress={() => console.log('Left Clicked!')}
activeOpacity={0.7}
/>
}
rightComponent={
<Icon
name={'mail-outline'}
color={'#00BB23'}
size={32}
onPress={() => navigation.navigate('Accounts')}
/>
}></Header>
<ImageBackground
source={{
uri: 'asset:/logo/bg.JPG',
}}
imageStyle={{borderRadius: 6}}
style={{
top: 15,
paddingTop: 95,
alignSelf: 'center',
width: 328,
height: 145,
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>
<Text
style={{
fontFamily: 'Poppins-Bold',
flexDirection: 'row',
paddingTop: 35,
fontSize: 15,
left: 30,
color: 'gray',
}}>
Recent Transactions
</Text>
</View>
<View style={{flex: 1, marginTop: 35}}>
{isLoading ? (
<ActivityIndicator />
) : (
<FlatList
data={transaction_details}
ItemSeparatorComponent={FlatListItemSeparator}
renderItem={({item}) => {
return (
<View>
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
}}>
<TextAvatar
backgroundColor={'#00BB23'}
textColor={'#f2f2f2'}
size={60}
type={'circle'}
// optional
>
{item.narration}
</TextAvatar>
<Text style={styles.narration}>{item.narration}</Text>
<Text style={styles.amountText}>{item.amount}</Text>
</View>
<Text style={styles.date_transaction}>{item.created_at}</Text>
</View>
);
}}
keyExtractor={item => item._id.toString()}
/>
)}
</View>
</View>
);
};
export default HomePage;
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
padding: 20,
},
paragraph: {
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
padding: 20,
},
text: {
top: -85,
fontSize: 30,
color: 'white',
textAlign: 'center',
fontFamily: 'Poppins-Bold',
},
mainContainer: {
paddingTop: 90,
justifyContent: 'center',
alignItems: 'center',
},
accText: {
top: -85,
paddingTop: 10,
justifyContent: 'center',
alignItems: 'center',
fontFamily: 'Poppins-Medium',
color: 'white',
textAlign: 'center',
},
PayeeName: {
justifyContent: 'flex-start',
flexWrap: 'wrap',
fontFamily: 'Poppins-Medium',
size: 800,
fontWeight: 'bold',
},
amountValue: {
textAlign: 'right',
fontFamily: 'Poppins-Medium',
size: 800,
fontWeight: 'bold',
},
narration: {
fontFamily: 'Poppins-ExtraBold',
size: 700,
left: -65,
},
date_transaction: {
fontFamily: 'Poppins-Regular',
size: 10,
left: 21,
},
amountText: {
fontFamily: 'Poppins-ExtraBold',
size: 1000,
right: 32,
},
});
Please I need help as I am not very good at styling here. Just need more guidiance in this case.
You need to wrap the item.narration and the item.created_at inside a <View> and have them aligned vertically. Basically wrap them on a View and swap item.amonut for item.created_at and style the <View> with a flex: 1. Then change the font size for the date.
<FlatList
data={transaction_details}
ItemSeparatorComponent={FlatListItemSeparator}
renderItem={({item}) => {
return (
<View>
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
}}>
<TextAvatar
backgroundColor={'#00BB23'}
textColor={'#f2f2f2'}
size={60}
type={'circle'}
// optional
>
{item.narration}
</TextAvatar>
<View style={{ flex: 1 }}> // Add styling as needed
<Text style={styles.narration}>{item.narration} </Text>
<Text style={styles.date_transaction}> {item.created_at}</Text> // Change the font size as you like
</View>
<Text style={styles.amountText}>{item.amount}</Text>
</View>
<Text style={styles.amountText}>{item.amount}</Text>
</View>
);
}}
keyExtractor={item => item._id.toString()}
/>

How do I align items properly in React native

I want the narration to be Bold , and should be afar left , the amount to be on the same row as the narration , the date should be far left below the narration. But what I do does not seem to work as the transactions list is somewhat not aligned and looks like this :
tried all I could, i do not seem to see it work fine.
My code is looking thus :
import React, {useEffect, useState} from 'react';
import {
ActivityIndicator,
Button,
Image,
ImageBackground,
SafeAreaView,
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
import {Header, Avatar, Icon, Card} from '#rneui/themed';
import {FlatList, ScrollView} from 'react-native-gesture-handler';
import {useNavigation} from '#react-navigation/native';
import {Tab} from '#rneui/base';
import AsyncStorage from '#react-native-async-storage/async-storage';
const HomePage = () => {
const [transaction_details, setTransaction_details] = useState([]);
const [isLoading, setLoading] = useState(true);
const navigation = useNavigation();
const Item = ({title}) => (
<View style={styles.item}>
<Text style={styles.title}>{title}</Text>
</View>
);
FlatListItemSeparator = () => {
return (
<View
style={{
height: 1,
width: 350,
backgroundColor: '#D3D3D3',
}}
/>
);
};
showdata = async () => {
let token = await AsyncStorage.getItem('token');
alert(token);
};
getTransactionsList = async () => {
let token = await AsyncStorage.getItem('token');
let email = await AsyncStorage.getItem('email');
fetch('https://******************/api/fetch-transaction/' + email, {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-type': 'application/json',
'Authorization': `Bearer ${token}`,
},
})
.then(response => response.json())
.then(responseJson => {
setTransaction_details(responseJson.results);
setLoading(false);
});
};
useEffect(() => {
//showdata();
getTransactionsList();
});
/*useEffect(() => {
fetch('https://brotherlike-navies.000webhostapp.com/people/people.php', {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-type': 'application/json',
},
})
.then(response => response.json())
.then(responseJson => {
setTransaction_details(responseJson);
setLoading(false);
});
}, []);
*/
return (
<View style={{flex: 1}}>
<Header
containerStyle={{
backgroundColor: 'transparent',
justifyContent: 'space-around',
}}
leftComponent={
<Avatar
small
rounded
source={{
uri: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSiRne6FGeaSVKarmINpum5kCuJ-pwRiA9ZT6D4_TTnUVACpNbzwJKBMNdiicFDChdFuYA&usqp=CAU',
}}
onPress={() => console.log('Left Clicked!')}
activeOpacity={0.7}
/>
}
rightComponent={
<Icon
name={'mail-outline'}
color={'#00BB23'}
size={32}
onPress={() => navigation.navigate('Accounts')}
/>
}></Header>
<ImageBackground
source={{
uri: 'asset:/logo/bg.JPG',
}}
imageStyle={{borderRadius: 6}}
style={{
top: 15,
paddingTop: 95,
alignSelf: 'center',
width: 328,
height: 145,
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>
<Text
style={{
fontFamily: 'Poppins-Bold',
flexDirection: 'row',
paddingTop: 55,
fontSize: 15,
left: 18,
color: 'gray',
}}>
Recent Transactions
</Text>
</View>
<View style={{flex: 1, marginTop: 35}}>
{isLoading ? (
<ActivityIndicator />
) : (
<FlatList
style={{fontFamily: 'Poppins-Medium', alignSelf: 'center'}}
ItemSeparatorComponent={this.FlatListItemSeparator}
data={transaction_details}
renderItem={({item}) => {
//console.log(item);
return (
<View style={{flex: 2, flexDirection: 'row'}}>
<Text style={styles.PayeeName}>
{item.narration}
{' '}
</Text>
<Text style={styles.date_ofTransaction}>{item.date}</Text>
<Text style={styles.amountValue}>{item.amount}</Text>
</View>
);
}}
keyExtractor={item => item.id.toString()}
/>
)}
</View>
</View>
);
};
export default HomePage;
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
padding: 20,
},
date_ofTransaction: {
marginTop: 20,
alignItems: 'flex-start',
alignItems: 'center',
left: -85,
fontFamily: 'Poppins-Light',
fontSize: 9,
},
paragraph: {
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
padding: 20,
},
text: {
top: -85,
fontSize: 30,
color: 'white',
textAlign: 'center',
fontFamily: 'Poppins-Bold',
},
mainContainer: {
paddingTop: 90,
justifyContent: 'center',
alignItems: 'center',
},
accText: {
top: -85,
paddingTop: 10,
justifyContent: 'center',
alignItems: 'center',
fontFamily: 'Poppins-Medium',
color: 'white',
textAlign: 'center',
},
PayeeName: {
justifyContent: 'flex-start',
alignItems: 'center',
left: 23,
fontFamily: 'Poppins-Medium',
size: 800,
fontWeight: 'bold',
},
amountValue: {
flexDirection :'row',
alignItems: 'flex-end',
fontFamily: 'Poppins-Medium',
size: 800,
fontWeight: 'bold',
},
});
The alignment is quite poor, however, I wish i could be shown a guide as how to go about this. So I could follow along etc. New to some form of Design in React native, as I am learning it on my own.
what about this approach. not sure if {' '} in you code is necessary. this aligns with space between and looks better for the ui instead of giving a random space to separate the items. and also apply the rest oft he styles to your liking, for example make font bold, etc.
<FlatList
data={transaction_details}
ItemSeparatorComponent={this.FlatListItemSeparator}
renderItem={({ item }) => {
return (
<View>
<View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>
<Text>{item.narration}</Text>
<Text>{item.amount}</Text>
</View>
<Text>{item.date}</Text>
</View>
)
}}
keyExtractor={(item) => item.id.toString()}
/>

React Native Flatlist not rendering but show ActivityIndicator

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.

My React native button text is not appearing in iOS but in android it works fine

Problem:
In my react native application I have used tochableOpacity for my buttons. I have created a custom button component and Have reused it through out the Application. My Custom button component is look like this.
const SubmitButton = (props) => {
const { onpress, btext, loadding, disabled, scrollView } = props;
const isLargeScreen = useIsLargeDevice();
return (
<TouchableOpacity
style={scrollView ? styles.sendButtonScrollView : styles.sendButton}
onPress={onpress}
disabled={disabled}>
{loadding ? (
<Image
source={spinner}
style={scrollView ? styles.bimageScrollview : styles.bimage}
/>
) : (
<Text
style={[
styles.sendButtonText,
isLargeScreen ? styles.largeText : styles.text,
]}>
{btext}
</Text>
)}
</TouchableOpacity>
);
};
export default SubmitButton;
const styles = StyleSheet.create({
sendButton: {
flex: 1,
backgroundColor: '#3e92ff',
paddingTop: '6%',
paddingBottom: '6%',
alignItems: 'center',
borderRadius: 50,
marginTop: 25,
justifyContent: 'center',
// flexWrap: 'wrap'
},
sendButtonScrollView: {
flex: 1,
backgroundColor: '#3e92ff',
paddingTop: '3%',
paddingBottom: '3%',
alignItems: 'center',
borderRadius: 50,
marginTop: 25,
justifyContent: 'center',
},
sendButtonText: {
fontFamily: 'Montserrat-Medium',
color: '#ffffff',
fontWeight: '300',
textAlign: 'center',
letterSpacing: 2,
},
text: {
fontSize: normalize(14),
},
largeText: {
fontSize: normalize(13),
},
bimage: {
width: 48,
height: 48,
},
bimageScrollview: {
width: 25,
height: 25,
},
});
And I have used it in another component like this.
Platform.OS === 'ios' ? Icon.loadFont() : null;
const handleBackButton = () => {
return true;
};
const _navigateToLogin = (navigation) => {
navigation.navigate('Login');
};
const _onPress = (values, validateToken) => {
validateToken(values.token);
};
const Tocken = (props) => {
useEffect(() => {
BackHandler.addEventListener('hardwareBackPress', handleBackButton);
}, [props.navigation]);
useEffect(() => {
if (props.validtoken === true) {
_navigateToLogin(props.navigation);
props.cleardata();
}
}, [props]);
return (
<KeyboardAvoidingView style={styles.container} enabled behavior={Platform.OS === 'ios' ? 'height' : null}>
<View style={styles.colmty} />
<View style={styles.formContainer}>
<AppText styles={styles.loginFormTitle}>
{strings('token.title')}
</AppText>
<Formik
initialValues={{
token: '',
}}
validationSchema={Yup.object({
token: Yup.string().required(strings('token.token-validation')),
})}
onSubmit={(values, formikActions) => {
_onPress(values, props.validatetoken);
setTimeout(() => {
formikActions.setSubmitting(false);
}, 500);
}}>
{(formprops) => (
<View>
<View
style={
!formprops.values.token &&
!formprops.errors.token &&
!props.hasError
? styles.inputView
: formprops.values.token &&
!formprops.errors.token &&
!props.hasError
? styles.validInputView
: styles.inputViewError
}>
<TextInput
style={styles.textField}
placeholder={strings('token.token_place_holder')}
placeholderTextColor="#bbbbbb"
value={formprops.values.token}
onChangeText={formprops.handleChange('token')}
onBlur={formprops.handleBlur('token')}
keyboardType="default"
/>
{formprops.errors.token || props.hasError ? (
<Icon
name="times"
size={normalize(15)}
style={styles.errorIcon}
/>
) : null}
{formprops.values.token &&
!formprops.errors.token &&
!props.hasError ? (
<Icon
name="check"
size={normalize(15)}
style={styles.validIcon}
/>
) : null}
</View>
{formprops.touched.token &&
formprops.errors.token &&
!props.hasError ? (
<View style={styles.errorMessage}>
<AppText styles={styles.errorMessageText}>
{formprops.errors.token}
</AppText>
</View>
) : null}
{props.hasError ? (
<View style={styles.errorMessage}>
<AppText styles={styles.errorMessageText}>
{props.error}
</AppText>
</View>
) : null}
<View style={styles.submitButtonView}>
<SubmitButton
btext={strings('token.submit')}
onpress={formprops.handleSubmit}
loadding={props.loadding}
disabled={props.loadding}
/>
</View>
</View>
)}
</Formik>
</View>
<View style={styles.colmty2} />
<View style={styles.hr} />
<View style={styles.versionContainer}>
<AppText styles={styles.version}>version: {version}</AppText>
</View>
</KeyboardAvoidingView>
);
};
const mapStateToProps = (state) => {
return {
loadding: state.signin.loadding,
validtoken: state.signin.validtoken,
hasError: state.signin.tokenEr,
error: state.signin.error,
};
};
const mapDispatchToProps = (dispatch) => {
return {
validatetoken: (value) => dispatch(signinActions.validatetoken(value)),
cleardata: () => dispatch(signinActions.cleardata()),
};
};
export default connect(mapStateToProps, mapDispatchToProps)(Tocken);
styles that I have used in the Token component is looks like this.
import {StyleSheet} from 'react-native';
import normalize from '_utils/fontsize';
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#ffffff',
},
colmty: {
height: '20%',
},
formContainer: {
height: '55%',
// backgroundColor: '#f2f2f2',
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
// elevation: 5,
padding: '10%',
justifyContent: 'center',
paddingBottom: '5%',
},
colmty2: {
height: '10%',
},
bottom: {
height: '15%',
justifyContent: 'center',
alignItems: 'center',
},
hr: {
borderBottomColor: '#c3c3c3',
borderBottomWidth: 2.0,
marginRight: '10%',
marginLeft: '10%',
},
validIcon: {
marginTop: 15,
color: '#3e92ff',
},
errorIcon: {
marginTop: 15,
color: '#ff3d3d',
},
textField: {
flex: 1,
fontFamily: 'Montserrat-Medium',
fontSize: normalize(15),
fontWeight: '500',
paddingLeft: 0,
},
inputView: {
marginTop: '5%',
flexDirection: 'row',
borderBottomColor: '#cccccc',
borderBottomWidth: 2,
},
validInputView: {
marginTop: '5%',
flexDirection: 'row',
borderBottomColor: '#3e92ff',
borderBottomWidth: 2,
},
inputViewError: {
marginTop: '5%',
flexDirection: 'row',
borderBottomColor: '#ff3d3d',
borderBottomWidth: 2,
},
patientFormTitle: {
fontSize: 30,
fontWeight: '200',
fontStyle: 'normal',
textAlign: 'center',
color: '#444444',
alignItems: 'center',
},
bottomLinkText: {
fontSize: 13,
color: '#484848',
borderBottomWidth: 2,
borderBottomColor: '#c3c3c3',
},
loginFormTitle: {
fontSize: normalize(16),
fontWeight: '200',
fontStyle: 'normal',
textAlign: 'center',
color: '#444444',
alignItems: 'center',
marginTop: '-10%',
},
errorMessageText: {
color: '#ff3d3d',
fontSize: normalize(13),
marginTop: 10,
},
spinnerContainer: {
marginTop: '50%',
alignItems: 'center',
},
versionContainer: {
marginRight: '10%',
marginLeft: '10%',
marginTop: '10%',
},
version: {
textAlign: 'center',
fontSize: normalize(12),
},
});
export default styles;
But button is not showing the text it looks like this.
I tried lot to find out where I have done wrong but I was unable to do so. Can someone help me to solve this issue.Thank you