I try to pass a object parameter by onPress() in PlanScreen to PlanDetailScreen, but error occurred as 'TypeError; undefined is not an object(evaluating 'detail.weekNumber').
How to solve it?
function PlanDetailScreen({ detail }) {
return (
<SafeAreaView>
<Text key={detail.weekNumber}>{"Week " + detail.weekNumber}</Text>
</SafeAreaView>
);
}
function PlanScreen({ navigation }) {
return (
<FlatList
numColumns={5}
data={PlanData}
renderItem={({ detail }) => (
<TouchableOpacity
onPress={(detail) =>
navigation.navigate("PlanDetailScreen", { detail })
}
>
<Text key={detail.weekNumber}>{"Uke\n" + detail.weekNumber}</Text>
</TouchableOpacity>
)}
/>
);
}
What Muhammad said is right, but you also have to take into account that navigation params come in the route prop of the screen.
It would look something like this:
function PlanDetailScreen({ route }) {
return (
<SafeAreaView>
<Text key={detail.weekNumber}>{"Week " + route.params.detail.weekNumber}</Text>
</SafeAreaView>
);
}
function PlanScreen({ navigation }) {
return (
<FlatList
numColumns={5}
data={PlanData}
renderItem={({ detail }) => (
<TouchableOpacity
onPress={() =>
navigation.navigate("PlanDetailScreen", { detail })
}
>
<Text key={detail.weekNumber}>{"Uke\n" + detail.weekNumber}</Text>
</TouchableOpacity>
)}
/>
);
}
Take a look at:
https://reactnavigation.org/docs/params/
You are overriding detail that is why detail is undefined just remove it from onPress
function PlanDetailScreen({ detail }) {
return (
<SafeAreaView>
<Text key={detail.weekNumber}>{"Week " + detail.weekNumber}</Text>
</SafeAreaView>
);
}
function PlanScreen({ navigation }) {
return (
<FlatList
numColumns={5}
data={PlanData}
renderItem={({ detail }) => (
<TouchableOpacity
onPress={() =>
navigation.navigate("PlanDetailScreen", { detail })
}
>
<Text key={detail.weekNumber}>{"Uke\n" + detail.weekNumber}</Text>
</TouchableOpacity>
)}
/>
);
}
Related
const Item = ({ item }) => (
<TouchableOpacity
onPress={() => this.navigation.navigate(
"carProfile",
{item: item}
)}>
<View style={styles.item}>
<Text style={styles.title}>{item.name}</Text>
<Text style={styles.details}>{item.details}</Text>
</View>
</TouchableOpacity>
);
const List = (props,navigation) => {
const renderItem = ({ item }) => {
if (props.searchPhrase === "") {
return <Item item={item} />;
}
if (item.name.toUpperCase().includes(props.searchPhrase.toUpperCase().trim().replace(/\s/g, ""))) {
return <Item item={item} />;
}
if (item.details.toUpperCase().includes(props.searchPhrase.toUpperCase().trim().replace(/\s/g, ""))) {
return <Item item={item} />;
}
};
return (
<SafeAreaView style={styles.list__container}>
<View
onStartShouldSetResponder={() => {
props.setClicked(false);
}}
>
<FlatList
data={props.data}
renderItem={renderItem}
keyExtractor={(item) => item.id}
/>
</View>
</SafeAreaView>
);
};
export default List;
the error is continuing to be there despite me trying to put navigation container in different positions. I want to send the user to the carProfile page, where the data passed in item is reused. This way user can know about the selection they are looking for
Use this way
onPress={() => this.props.navigation.navigate(
"carProfile",
{item: item}
)}
The navigation is inside the props, not as a second argument. Below is a classic example. And also note, you cannot extract navigation prop for child components, it will only work on Main components(Screens).
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}
If you want to use navigation inside child components, you can use the navigation hooks.
import { useNavigation } from "#react-navigation/native";
function MyBackButton() {
const navigation = useNavigation();
return (
<Button
title="Back"
onPress={() => {
navigation.goBack();
}}
/>
);
}
I'm in category page and when i press any of them, it navigates me to the that categories product list. so far so good. when i go back and press another category i get previous categories product list.
there is my some of code
this is how i navigate to product list
render() {
const {navigation} = this.props.navigation;
const categories = category.map((item, index) => {
return (
<TouchableOpacity
key={index}
styles={styles.category}
onPress={() =>
navigation.navigate('ProductList', {
categoryName: item.Menu,
})
}>
<Text> {item.Menu} </Text>
</TouchableOpacity>
);
});
return (
<View style={styles.container}>
{this.state.isData ? (
<View style={styles.container}>
<Text style={styles.title}>Category</Text>
{categories}
</View>
) : (
<ActivityIndicator size="large" color="#0B970B" />
)}
</View>
);
}
}
and this is where i go, i can get navigation props ext. but i cant find where the problem is
import React,{useState,useEffect} from 'react';
import {
View,
ScrollView,
Text,
Image,
StyleSheet,
Dimensions,
ActivityIndicator,
} from 'react-native';
const List = ({navigation}) => {
const [isData, setIsData] = useState(false);
useEffect(() => {
getData();
return null;
}, []);
const getData = async () => {
if (navigation?.route?.params?.categoryName) {
categoryName = navigation.route.params.categoryName;
fetch(global.apiPost + global.token, requestOptions)
.then((response) => response.json())
.then((result) => {
result.forEach((element) => {
if (element.Menu === categoryName) {
products.push(element);
}
});
setIsData(true);
console.log(products, 'products');
console.log(productsByAccessory, 'productsByAccessory');
console.log(productsByTravel, 'productsByTravel');
console.log(productsByBag, 'productsByBag');
})
.catch((error) => console.log('error', error));
}
};
return (
<View style={{flex: 1}}>
<Text style={styles.title}>{categoryName}</Text>
{isData ? (
<View style={{flex: 1}}>
<View style={styles.itemFounds}>
<Text>{data.length + ' item founds'}</Text>
</View>
<View style={{flexDirection: 'row', flexWrap: 'wrap'}}>
<Text>
{productsByAccessory.length} / {productsByTravel.length} /{' '}
{productsByBag.length} / {products.length} asd
</Text>
</View>
</View>
) : (
<ActivityIndicator size="large" color="#0B970B" />
)}
</View>
);
}
export default List
Change your render method
const { navigation } = this.props; // Here was the error
const categories = category.map((item, index) => {
return (
<TouchableOpacity
key={index}
styles={styles.category}
onPress={() =>
navigation.navigate("ProductList", {
categoryName: item.Menu,
})
}
>
<Text> {item.Menu} </Text>
</TouchableOpacity>
);
});
render() {
return (
<View style={styles.container}>
{this.state.isData ? (
<View style={styles.container}>
<Text style={styles.title}>Category</Text>
{categories}
</View>
) : (
<ActivityIndicator size="large" color="#0B970B" />
)}
</View>
);
}
}
render method should have the return statement only. Don't perform any operations inside the render method. Now it should work.
I want to delete item from the FlatList. However, the solution from here is not working for my code. When I run my code, I am getting error such as 'index is not defined'.
I have yet to find other post regarding this issue so any help would be greatly appreciated.
Code snippet provided below:
export default class FrCreateScreen extends Component {
constructor(props) {
super(props);
this.state = {
//new timeSlots
timeSlots: [],
}
}
setEndTime = (event, appointmentEndTime, textEndTime) => {
appointmentEndTime = appointmentEndTime || this.state.appointmentEndTime;
textEndTime = textEndTime || moment(appointmentEndTime).format('h:mm a').toString();
this.setState({
showEndTime: Platform.OS === 'ios' ? true : false,
appointmentEndTime,
textEndTime,
timeSlots: [
...this.state.timeSlots,
{
apptdate: this.state.textAppointmentDate,
appttime: this.state.textAppointmentTime,
endTime: textEndTime,
}
],
});
}
deleteDateTime = (id) => {
const filteredData = this.state.timeSlots.filter(item => item.id !== id);
this.setState({ timeSlots: filteredData });
}
render() {
return (
<ScrollView>
...
<View>
<FlatList
data={this.state.timeSlots}
keyExtractor={({ id }, index) => index.toString()}
renderItem={({ item }) => {
return (
<View style={styles.containerList}>
...
<TouchableOpacity onPress={() => this.deleteDateTime(index)}>
<Feather name="trash" style={styles.icon} />
</TouchableOpacity>
</View>
</View>
);
}}
/>
</View>
</ScrollView>
)
};
};
Screenshot below:
I think you need to add index inside renderItem { item, index }
renderItem = {({ item, index }) => {
return (
<View style={styles.containerList}>
<TouchableOpacity onPress={() => this.deleteDateTime(index)}>
<Feather name="trash" style={styles.icon} />
</TouchableOpacity>
</View>
);
}}
While rendering in map function , it provides the index too, so try adding that.
renderItem={({ item,index }) => {
return (
<View style={styles.containerList}>
...
<TouchableOpacity onPress={() => this.deleteDateTime(index)}>
<Feather name="trash" style={styles.icon} />
</TouchableOpacity>
</View>
</View>
);
}}
Hope it helps
ok fixed. on touchable onPress, the argument should be 'item.index' instead of 'index'.
here's the correct code:
renderItem={({ item,index }) => {
return (
<View style={styles.containerList}>
...
<TouchableOpacity onPress={() => this.deleteDateTime(item.index)}>
<Feather name="trash" style={styles.icon} />
</TouchableOpacity>
</View>
</View>
);
}}
I am not able to show my flatlist and I am not sure whether my coding is correct. There is no output if when I run this. It will only show a white screen. My data is correct which is this.props.section.songs. I want to show the title and artist in my text but I am unable to do that.
export default class SongList extends Component
{
renderSongsList() {
return(
<View>
<FlatList
data = {this.props.section.songs}
renderItem={(song, sectionId, rowId) => (
<TouchableOpacity onPress={ () => Actions.Player({songIndex: parseInt( rowId ),songs: this.props.section.songs, section: this.props.section }) }>
<View key={song} style={ styles.song }>
<Text style={styles.itemTitle}>
{ song.title}
</Text >
<Text style={styles.itemArtist}>
{ song.artist }
</Text>
</View>
</TouchableOpacity>
)}
/>
</View>
);
}
render()
{
return (
<View>
{ this.renderSongsList() }
</View>
);}}
export default class SongList extends Component
{
renderSongsList() {
return(
<View>
<FlatList
data = {this.props.section.songs}
// You have to cross check the values you receive here. Better is to receive a array item
//here and pass to the render props
// Or try {song, sectionId, rowId} this in place of (song, sectionId, rowId) see below
renderItem={({song, sectionId, rowId}) => (
<TouchableOpacity onPress={ () => Actions.Player({songIndex: parseInt( rowId ),songs: this.props.section.songs, section: this.props.section }) }>
<View key={song} style={ styles.song }>
<Text style={styles.itemTitle}>
{ song.title}
</Text >
<Text style={styles.itemArtist}>
{ song.artist }
</Text>
</View>
</TouchableOpacity>
)}
/>
</View>
);
}
render()
{
return (
<View>
{ this.renderSongsList() }
</View>
);}}
export default class SongList extends Component
{
renderItems(item){
// Here you can access all items of your json by item.property
// Like your JSON is { id: '1', title: 'Better Now', artist: 'Post Malone', }
// You can access these values as item.id, item.title etc
}
renderSongsList() {
return(
<View>
<FlatList
data = {this.props.section.songs}
renderItem={(item) => this.renderItems(item)}
/>
</View>
);
}
render()
{
return (
<View>
{ this.renderSongsList() }
</View>
);}}
I have code
AsyncStorage.getItem("Friends").then((value) => {
this.setState({"Friends": value});
}).done();
I am trying to show in list using
render() {
return ({
this.state.Friends.map((o,i) => {
<View key={i} style={styles.row}>
<View>
<Text style={styles.app_type_name}>{o.name}</Text>
</View>
</View>
})
})
}
I am getting
error evaluating object 'this.state.Friends'
You render method should looks like :
render() {
const {Friends} = this.state;
return (
<div>
{
Friends && Friends.map((o,i) =>
<View key={i} style={styles.row}>
<View><Text style={styles.app_type_name}>{o.name}</Text></View>
</View>
)
}
</div>
);
}