This is my data
[{"size":"Small","price":"90"},{"size":"Large","price":"180"},{"size":"Extra Large","price":"200"}]
and this is my code
const route = useRoute();
const [datas, setDatas] = useState([]);
useEffect(() => {
setDatas(route.params.item_sizes);
},[])
const ItemSizes = () => {
if(datas.length > 0)
{
console.log("Item size data: ", datas); //for debugging purposes
return(
<View>
{datas.map((data,key) => (
<View key={key}>
<View style={{flex:0.2}}>
<MaterialCommunityIcons name={"radiobox-blank"} size={20} color={'gray'}/>
{/* <Text style={{fontSize:16, fontWeight:'bold'}}>Icon</Text> */}
</View>
<View style={{flex:1}}>
<Text style={{fontSize:16, fontWeight:'bold'}}>{data.size}</Text>
</View>
<View style={{flex:1, flexDirection:'row-reverse'}}>
<Text style={{fontSize:16, fontWeight:'bold'}}>{data.price}</Text>
</View>
</View>
))}
</View>
)
}
}
I call it from my view like this
return (
<View>
{ItemSizes()}
</View>
)
So after I checked there's a data on datas so why it is undefined? Please do explain why it is returning me undefined even though there's a data?? Thank you
Check if the data you are setting is an array or string. If it's string set it like below by parsing
setData(JSON.parse(route.params.item_sizes));
I want to use localStorage and move to another page at the same time, but only moving work, I can't get the value
const pressHandlerMapTest = () => {
navigation.navigate("TestMapScreen");
};
return (
<ImageBackground style={styles.background}>
<View style={styles.tourWindow}>
<TouchableOpacity underlayColor="red"
onPress={pressHandlerMapTest}
onPressIn={() => {
localStorage.setItem('tour', 'others');
}}>
<Image source={require("../assets/royals.png")} ></Image>
</TouchableOpacity>
</View>
</ImageBackground>
);
const pressHandlerMapTest = () => {
localStorage.setItem('tour', 'others');
navigation.navigate("TestMapScreen");
};
return (
<ImageBackground style={styles.background}>
<View style={styles.tourWindow}>
<TouchableOpacity underlayColor="red"
onPress={pressHandlerMapTest}
>
<Image source={require("../assets/royals.png")} ></Image>
</TouchableOpacity>
</View>
</ImageBackground>
);
I am a newbie, I'm having trouble getting the number format when passing data from flatList to modal. It is worth mentioning here that when I format in the flatlist, it does not have an error, but when transferred to the modal, it fails.
>TypeError: undefined is not an object (evaluating 'number.toFixed')
Declaration functions
const [{user}, dispatch] = useValueContext();
const navigation = useNavigation();
const [data, setData] = useState([]);
const [modalVisible, setModalVisible] = useState(false);
const [selectedItem, setSelectedItem] = useState([]);
const [maxId, setMaxId] = useState('0');
const [loading, setLoading] = useState(false);
const [isListEnd, setIsListEnd] = useState(false);
const [modalFilterVisible, setModalFilterVisible] = useState(false);
const handleOnSelectItem = ({item}) => {
setSelectedItem(item);
};
const handleOnCloseModal = () => {
setSelectedItem([]);
};
Modal function
const ModalView = ({item}) =>{
return(
<Modal
animationType="none"
transparent={true}
visible={modalVisible}
onRequestClose={handleOnCloseModal}
>
<TouchableOpacity
style={styles.modal_content}
activeOpacity={1}
onPressOut={() => {setModalVisible(false)}}
>
<TouchableWithoutFeedback style={styles.modalView}>
<View style={styles.modal_header}>
<TouchableOpacity
style={{
marginEnd: 5
}}
onPress={() => {
setModalVisible(!modalVisible);
}}
>
<FontAwesome5 name="times" size={16} />
</TouchableOpacity>
</View>
<View style={styles.modal_body}>
<View style={{}}>
<Text style={styles.detail_content_name}>{item.MoneyAction_Name}</Text>
<View style={styles.detail_content_status}>
<Text style={styles.detail_content_status_text}>{item.MoneyStatus_Name}</Text>
</View>
{item.Money_Value > 0 ?
(<Text style={{color: '#56ab2f', fontSize: 17, textAlign: 'center'}}>+{item.Money_Value.toFixed(1).replace(/\d(?=(\d{3})+\.)/g, '$&,').replace(/\./g, ' ').replace(/\,/g, '.').replace(/\ /g, ',')} {item.Money_Ticker}</Text>)
:(<Text style={{color: '#e41318', fontSize: 17, textAlign: 'center'}}>{item.Money_Value.toFixed(1).replace(/\d(?=(\d{3})+\.)/g, '$&,').replace(/\./g, ' ').replace(/\,/g, '.').replace(/\ /g, ',')} {item.Money_Ticker}</Text>)
}
<View style={{marginBottom: 16, marginTop: 16, borderStartColor: 'rgba(0,0,0,.1)', borderWidth: .3, alignItems:'stretch'}}>
</View>
<View style={styles.detail_list}>
<Text>Nguồn tiền</Text>
<Text>Ví {item.Money_Ticker}</Text>
</View>
{item.Money_PartnerGiftCode !== '' ? (
<View style={styles.detail_list}>
<Text>Mã nâng cấp</Text>
<Text>{item.Money_PartnerGiftCode}</Text>
</View>
): null}
<View style={styles.detail_list}>
<Text>Phí giao dịch</Text>
</View>
<View style={styles.detail_list}>
<Text>Mã giao dịch</Text>
<Text>#632542</Text>
</View>
<View style={styles.detail_list}>
<Text>Thời gian</Text>
<Text>19/10/2020 23:21</Text>
</View>
</View>
</View>
</TouchableWithoutFeedback>
</TouchableOpacity>
</Modal>
);
}
Item function:
const Item = ({item}) => {
return(
<TouchableOpacity
style={styles.history_li}
onPress={() => {
handleOnSelectItem({item})
setModalVisible(true)
}}
>
<View style={styles.history_view}>
<View style={styles.history_view_left}>
<Text style={styles.history_view_left_name}>{item.MoneyAction_Name}</Text>
<Text style={styles.history_view_left_time}>
{new Date(item.Money_Time * 1000).getDate()}
/{new Date(item.Money_Time * 1000).getMonth()}
/{new Date(item.Money_Time * 1000).getFullYear()} {new Date(item.Money_Time * 1000).getHours()}
:{new Date(item.Money_Time * 1000).getMinutes()}
:{new Date(item.Money_Time * 1000).getSeconds()}
</Text>
</View>
<View style={styles.history_view_right}>
{item.Money_Value > 0 ?
(<Text style={styles.history_view_right_receive}>+{item.Money_Value.toFixed(1).replace(/\d(?=(\d{3})+\.)/g, '$&,').replace(/\./g, ' ').replace(/\,/g, '.').replace(/\ /g, ',')}</Text>)
:(<Text style={styles.history_view_right_pay}>{item.Money_Value.toFixed(1).replace(/\d(?=(\d{3})+\.)/g, '$&,').replace(/\./g, ' ').replace(/\,/g, '.').replace(/\ /g, ',')}</Text>)
}
<Text style={styles.history_view_right_currency}>{item.Money_Ticker}</Text>
</View>
</View>
</TouchableOpacity>
);
}
const _renderItem = ({item}) => {
return(
<Item item = {item} />
);
}
executable function
return (
<View style={styles.container}>
<View style={{padding: 5, flexDirection: 'row', justifyContent:'space-between'}}>
<View style={styles.HeaderScreen}>
<Image
style={styles.imgStyle}
source={require('../assets/images/vietsmile.png')}
/>
<Text style={styles.title}>Lịch sử</Text>
</View>
<View style={styles.bell}>
<Ionicons name="ios-notifications" size={26} color="#596475" />
</View>
<View lightColor="#eee" darkColor="rgba(255,255,255,0.1)" />
</View>
<View style={{backgroundColor: '#f1f2f3'}}>
<View style={styles.filter_menu}>
<TouchableOpacity
style={styles.shop_filter}
onPress={()=>{setModalFilterVisible(true)}}
>
<FontAwesome5 name="filter" size={16} color="#3696D9" />
<Text style={{marginLeft: 3, color: '#3696D9',}}>Bộ lọc</Text>
</TouchableOpacity>
</View>
<FlatList
data={data}
renderItem={_renderItem}
keyExtractor={item => item.Money_ID.toString()}
ListFooterComponent={renderFooter}
/>
</View>
{selectedItem !== [] ? (
<ModalView item={selectedItem} />
) : null}
</View>
);
Please help me
I have a list of many items where each item has TextInput and TouchableOpacity wrapped by View.
I've trying to set focus on TextInput in the list item in which TouchableOpacity has been pressed. It's needed for editing each item's name.
Below is the code of how I tried to do this. The problem of this code is that after pressing on any of the TouchableOpacity the last TextInput will always be focused due to the fact that the last iteration overwrites textInputRef.
Is there a way to make textInputRef contain a reference to the TextInput which TouchableOpacity will press?
const ListComponent = ({list}) => {
const textInputValue = useRef('');
const textInputRef = useRef(null);
changeItemName = (text) => {
textInputValue.current = text;
};
return (
<ScrollView>
{list.length > 0 &&
list.map((item) => (
<View key={item._id}>
<TouchableOpacity>
<View
<Text>{`Item: `}</Text>
<TextInput ref={textInputRef} onChangeText={changeItemName}>
{item.name}
</TextInput>
</View>
</TouchableOpacity>
<TouchableOpacity
onPress={() => {
textInputValue.current = '';
}}>
<Icon name={'check'} size={25} color="#000" />
</TouchableOpacity>
<View>
<TouchableOpacity
onPress={() => {
textInputValue.current = item.name;
textInputRef.current.focus();
}}>
<Icon name={'edit'} size={25} color="#000" />
</TouchableOpacity>
</View>
</View>
))}
</ScrollView>
);
};
I think creating an array of ref will help you to resolve.
Try this way
const ListComponent = ({list}) => {
const textInputValue = useRef('');
const textInputRef = useRef(null);
changeItemName = (text) => {
textInputValue.current = text;
};
const collectionRef = useRef(list.map(() => createRef()));
return (
<ScrollView>
{list.length > 0 &&
list.map((item, index) => (
<View key={item._id}>
<TouchableOpacity>
<View
<Text>{`Item: `}</Text>
<TextInput ref={collectionRef.current[index]} onChangeText={changeItemName}>
{item.name}
</TextInput>
</View>
</TouchableOpacity>
<TouchableOpacity
onPress={() => {
textInputValue.current = '';
}}>
<Icon name={'check'} size={25} color="#000" />
</TouchableOpacity>
<View>
<TouchableOpacity
onPress={() => {
textInputValue.current = item.name;
collectionRef[index].current.focus();
}}>
<Icon name={'edit'} size={25} color="#000" />
</TouchableOpacity>
</View>
</View>
))}
</ScrollView>
);
};
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>
);
}
}