FlatList Onpress show page with json data for each user - json

I have a endusers page where I fetch from an api and how the results in a flatlist as listitem.
I want to have one page for each user which shows their info but without creating userX.js for each user. So there should be only 1 page which is dynamically.
My Endusers.js View:
return (
<View style={styles.container}>
<View style={styles.headerContainer}>
<SearchBar
showLoading
placeholder={`Suchen: Name, Email oder Land...`}
lightTheme
round
onChangeText={text => this.searchFilterFunction(text)} />
</View>
<View style={styles.listContainer}>
<FlatList
style={styles.list}
data={this.state.data}
renderItem={({ item }) =>
<ListItem
titleStyle={styles.item}
subtitleStyle={styles.item}
title={`${item.strName} | ${item.strLand}`}
subtitle={`${item.strEmail}`}
containerStyle={{ borderBottomWidth: 0 }}
onPress={() => this.props.navigation.push('Userpage')}
/>}
keyExtractor={id => id}
/>
</View>
</View>
)
My Fetch method:
fetch(url)
.then((response) => response.json())
.then((responseJson) => {
this.setState({
data: upper(responseJson.sort((a, b) => (a.strName - b.strName))),
loading: false,
error: responseJson.error
})
this.searchArray = responseJson;
})
.catch((error) => {
console.log(error)
})
My Constructor:
constructor() {
super()
this.state = {
loading: true,
data: [],
error: null
}
this.searchArray = [];
}
In Endusers.js View when I click on listitem the Userpage.js should show with the info of the clicked user.
How should I go on about this problem? What are the keywords I need to
google/research to find a solution? I'm not her to just copy paste so
please don't get this question wrong^^

You can send params when you push the navigation:
this.props.navigator.push({
component: MyScene,
title: 'Scene ' + nextIndex,
passProps: {index: nextIndex},
});
You can send as passProps your item which i guess contains the details regarding your User, like this:
passProps: {item: item}
Hope I helped, and more details on react-native documentation https://facebook.github.io/react-native/docs/navigation.

Related

show a list of data in react native app from sql server

I wanted to show a list of data in my app, I already have backend API that can get the data from the server but when I trying to make it appear in my react native app, it wont appear. Below is the data that get from API
here is the code for show the data in a list view in react native apps
import React, { useState, useEffect,Component,onMount} from 'react';
import {View,Text, Button, StyleSheet,TextInput,ListView,ActivityIndicator,Platform} from 'react-native';
import {useNavigation} from'#react-navigation/native';
import {StatusBar} from'expo-status-bar';
export default function StopJob(){
const[isLoading,setIsLoading]=useState(true);
useEffect(()=>{
return fetch('http://localhost/api/findid.php',{
mode:'no-cors'
})
.then((response) => response.json())
.then((responseJson) => {
let ds = new ListView.DataSource({rowHasChanged: (r1, r2)=> r1 !== r2});
this.setState({
isLoading: false,
dataSource: ds.cloneWithRows(responseJson),
}, function() {
// In this block you can do something with new state.
});
})
.catch((error) => {
console.error(error);
})
},[]);
const Showlist=(user,job,jobid,machinecode,startTime)=>{
this.props.navigation.navigate('Third', {
Userid : user,
Job : job,
JobId : jobid,
MachineCode : machinecode,
StartTime : startTime
});
}
const ListViewItemSeparator = () => {
return (
<View
style={{
height: .5,
width: "100%",
backgroundColor: "#000",
}}
/>
);
}
if(isLoading)return(<View style={{flex: 1, paddingTop: 20}}><ActivityIndicator /> </View>);
return(
<View style={styles.MainContainer_For_Show_StudentList_Activity}>
<ListView
dataSource={this.state.dataSource}
renderSeparator= {this.ListViewItemSeparator}
renderRow={ (rowData) => <Text style={styles.rowViewContainer}
onPress={this.Showlist.bind(
this, rowData.user,
rowData.job,
rowData.jobid,
rowData.machinecode,
rowData.startTime
)} >
{rowData.job}
</Text> }
/>
</View>
);
}
const styles = StyleSheet.create({
MainContainer_For_Show_StudentList_Activity :{
flex:1,
paddingTop: (Platform.OS == 'ios') ? 20 : 0,
marginLeft: 5,
marginRight: 5
},
rowViewContainer: {
fontSize: 20,
paddingRight: 10,
paddingTop: 10,
paddingBottom: 10,
}
});
the expected output will only show the job from the database, but for now the function did not show the list view the error shown Text strings must be rendered within a component.
I was referring this webpage to implement the code : https://reactnativecode.com/insert-update-display-delete-crud-operations/
on the example it show function well but when I try to implement it, it cant work :(
updated but still having same error
export default function StopJob(){
const[isLoading,setIsLoading]=useState(true);
const[dataSource,setdataSource]=useState();
useEffect(()=>{
return fetch('http://localhost/api/findid.php')
.then((response) => response.json())
.then((responseJson) => {
let ds = new FlatList.DataSource({rowHasChanged: (r1, r2)=> r1 !== r2});
setIsLoading(false)
setdataSource(ds.cloneWithRows(responseJson))
})
.catch((error) => {
console.error(error);
})
},[]);
const Showlist=(user,job,jobid,machinecode,startTime)=>{
this.props.navigation.navigate('', {
Userid : user,
Job : job,
JobId : jobid,
MachineCode : machinecode,
StartTime : startTime
});
}
const ListViewItemSeparator = () => {
return (
<View
style={{
height: .5,
width: "100%",
backgroundColor: "#000",
}}
/>
);
}
if(isLoading)return(<View style={{flex: 1, paddingTop: 20}}><ActivityIndicator /> </View>);
return(
<View style={styles.MainContainer_For_Show_StudentList_Activity}>
<FlatList
dataSource={dataSource}
keyExtractor={item=>item.user}
ItemSeparatorComponent= {ListViewItemSeparator()}
renderItem={ (item) => <Text style={styles.rowViewContainer}>{item.job}</Text> }
/>
</View>
);
}
Ok here are the steps to follow:
Use flatlist
Your data source should be a regular array. So, you can use the response from your api as it is.
renderRow should change as renderItem
renderSeparator should change as ItemSeparatorComponent
here is the final form:
const[isLoading,setIsLoading]=useState(true);
const [data, setData]=useState([]);
.......
fetch('http://localhost/api/findid.php',{
mode:'no-cors'
})
.then((response) => response.json())
.then((responseJson) => {
//you can't use setState inside function components. :)
setData(responseJson);
setLoading(false);
})
.catch((error) => {
console.error(error);
})
.......
<FlatList
data={data}
keyExtractor={item => item.jobid} //it should be unique. change it
renderItem={({item}) => <Text>{item.job}</Text>}
/>
This should solve your issue for now but keep in mind these too:
Looks like you don't know differences between class components and function components. Do your research
Flatlist has it's own performance configurations. Research and implement them.

Objects are not valid as a React child (found: object with keys { my keys })

when I submit my form with the const onSubmit, I fetch data. If the submit form is ok, I want to extract the data I get from my api. So I use, setState reponse : my data, and then I want to pass this data (reponse) to the component SingleLayout.
But it doesn't work. I get this error : [Error: Objects are not valid as a React child (found: object with keys {ID, Post Title, post_date, Prix, Surface, Ville, Category, featured_image, mandats_signes, date_de_signature_du_compromis}). If you meant to render a collection of children, use an array instead.]
Here the code :
export default class QueryChild extends Component {
state = {
username: "",
password: "",
isLogged: null,
email: "",
reponse: '',
id: 4577
}
constructor(props) {
super(props);
this.render();
}
onSubmit = async() => {
const fetchValue = 'myAPI/suivi-dossier?' + 'username=' + this.state.username + '&password=' + this.state.password + '&id=' + this.state.id
try {
await fetch(fetchValue, {
method: 'GET'
})
.then((response) => response.json())
.then((responseJson) => {
if(responseJson.success === true) {
// I want to extract this :
this.setState({ reponse: responseJson.message })
this.setState({ isLogged: true })
} else {
this.setState({reponse : responseJson.message });
console.log(this.state.reponse)
}
// this.setState({
// data: responseJson
// })
})
.catch((error) => {
console.error(error);
});
} catch (err) {
console.log(err)
}
}
render() {
if(this.state.isLogged === true) {
// when user is Logged, I want to pass this.state.reponse to my component SingleLayout
// but I get the error : [Error: Objects are not valid as a React child
// (found: object with keys {ID, Post Title, post_date, Prix, Surface, Ville,
// Category, featured_image, mandats_signes, date_de_signature_du_compromis}). If you
// meant to render a collection of children, use an array instead.]
const SingleComponent = this.state.reponse.map(message => <SingleLayout key={message.ID} table={message}/> )
return (
<SafeAreaView>
{SingleComponent}
</SafeAreaView>
);
} else {
return (
<View style={styles.container}>
<ScrollView>
<ImageBackground source={image} resizeMode="cover" style={styles.image}>
<Spacer taille={70} />
<View style={styles.content}>
<Image
style={styles.imgLogo}
source={require('../../logo.png')}
/>
<Text style={styles.logo}>Pour des raisons de sécurité, veuillez entrer vos Identifiants</Text>
<View style={styles.inputContainer}>
<Text style={styles.textBasique}>{this.state.reponse}</Text>
<TextInput
placeholder='Identifiant ou adresse email'
style={styles.input}
value={this.state.username}
onChangeText={val => this.setState({ username: val})}
/>
<TextInput
placeholder='Mot de passe'
style={styles.input}
value={this.state.password}
secureTextEntry= {true}
onChangeText={val => this.setState({ password: val})}
/>
<Spacer taille={10} />
<Button title='Se Connecter' onPress={this.onSubmit}/>
<Spacer taille={10} />
</View>
</View>
<Spacer taille={200} />
</ImageBackground>
</ScrollView>
</View>
)
}
}
}
Thank you.
The response that comes from the server is an object. Since the "map" function only works with an array so, if you want to run this code you've to wrap "responseJson.message" into the array.
if(responseJson.success === true) {
this.setState({ reponse: [responseJson.message] })
this.setState({ isLogged: true })
}
Yes I get similar error after applying the solution because I found that the error comes from the setState reponse. So I added JSON.stringify and now the error is gone.
The code of Single Layout :
const SingleLayout = (props) => {
let id = props.id
let table = props.table
console.log(table)
const { colors } = useTheme();
return (
<View style={[styles.container, {backgroundColor: colors.background}]}>
<Text>Bravo</Text>
</View>
)
}
Now with the solution : const SingleComponent = Object.keys(this.state.reponse).map(key => )
it works but it send caracters one by one
SO I finally solved my problem :
the code i change :
QueryChild.tsx :
if(responseJson.success === true) {
//here :
this.setState({ reponse: JSON.stringify(responseJson.message) })
this.setState({ isLogged: true })
and I directly return SingleLayout like that :
return (
<SafeAreaView>
<SingleLayout table={this.state.reponse} />
</SafeAreaView>
Now I can access this.state.reponse into my SingleLayout :
const SingleLayout = (props) => {
let id = props.id
let table = props.table
const myObj = JSON.parse(table);
console.log(myObj[0].mandats_signes)
console.log(myObj[0].ID)
console.log(myObj[0].Category)
//etc...
const { colors } = useTheme();
return (
<View style={[styles.container, {backgroundColor: colors.background}]}>
<Text>Bravo</Text>
</View>
)
}
it's not a good practice to pass JSON and then parse.
I solved it and here is the link with the same solution that I presented to you:
https://codesandbox.io/s/peaceful-bouman-qyi5y?file=/src/App.js

How to get Id from postlist(posts.js) and show on post.js page in react native

I'm getting a list of news through api wordpress and displaying posts.js. Now I want to go to the 1post.js page by clicking on each item and displaying that particular item.
componentDidMount(){
return fetch('URL/wp/api/get_posts')
.then( (response) => response.json() )
.then( (responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson.posts,
})
})
.catch((error)=> {
});
} render() { if (this.state.isLoading){ return ( ) } else{ let posts=this.state.dataSource.map((val, key) => { return {val.title} }); return ( {posts} );
To navigate from one component to another, you need to create a navigation container. react-navigation is the official module for navigating between components.
Visit this link to create a stack navigator and then you can use below code to achieve the above said.
async componentDidMount() {
fetch('URL/wp/api/get_posts')
.then(res => res.json())
.then(data => this.setState({posts: data }))
}
renderPostList(){
return this.state.posts.map(post=>(
<TouchableOpacity onPress={this.props.navigation.navigate("NextScreen",{selectedPost:post})}>
<Text>{post.title}</Text>
</TouchableOpacity>
))
}
render() {
return (
<View>
{this.renderPostList()}
</View>
)
}

Populating a flatlist with json data, in react native, not possible?

I'm very new at react native, just starting to get the hang of it. Playing around with fetching json data from my dummy api and populating views with it.
Currently using a flatlist, which works fine! Except it doesn't work when I give it a very basic json array of items.
This is how the basic json data array looks:
[{"Note 1": "This is note number 1."}, {"Note 2": "This is note number 2."}, {"Note 3": "This is note number 3."}]
This is my very temporary and basic code I'm playing around with:
render() {
let apiData = fetch("address of my api which is not relevant, it works")
.then((response) => response.json())
.then((responseJson) => {
console.log(responseJson);
return responseJson;
})
.catch((error) => {
console.error(error);
});
console.log(apiData);
return (
<View style={styles.notesContainer}>
<FlatList
data={apiData}
renderItem={({ item }) => <Text style={styles.item}>{item.key}</Text>}
/>
</View>
);
}
The json array is very simple and just contains 3 objects. If I create a list of random stuff (as noted in the documentation with "Key: value", the flatlist works fine.
Can it really be true I need to handle a basic json array in some fashion before I can set is as a data source for a flatlist?
Use componentDidMount for fetching data from API and use state to store apiData.
So your code will be like:
constructor () {
super(props);
state = {
apiData:[]
};
}
componentDidMount =()=>{
fetch("address of my api which is not relevant, it works")
.then((response) => response.json())
.then((responseJson) => {
console.log(responseJson);
this.setState({apiData: responseJson});
})
.catch((error) => {
console.error(error);
});
}
render() {
return (
<View style={styles.notesContainer}>
<FlatList
data={this.state.apiData}
renderItem={({ item }) => <Text style={styles.item}>{item.key}</Text>}
/>
</View>
);
}

How do I get the json nested object?

I am new to React Native, and want to get the nested object from json. Here is my code. And I can get succesfuly data.phone but always get this if I try to get data.name.title or etc.
undefined is not an object
Here is my code.
class Dictionary extends Component {
// Initialize the hardcoded data
constructor(props) {
super(props);
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows([
'John', 'Joel', 'James', 'Jimmy', 'Jackson', 'Jillian', 'Julie', 'Devin'
])
};
fetch('http://api.randomuser.me/?results=50')
.then((response) => response.json())
.then((responseJson) => {
//return responseJson.movies;
console.log( responseJson.results );
this.setState({
dataSource: ds.cloneWithRows(responseJson.results),
loaded:false,
})
})
.catch((error) => {
console.error(error);
});
}
render() {
return (
<View
style={styles.container}>
<ListView
dataSource={this.state.dataSource}
renderRow={(data) =>
<View>
<Text>
{data.phone}
</Text>
<Text>
{data.name.title}
</Text>
</View>
}
renderSeparator={(sectionId, rowId) => <View key={rowId} style={styles.separator} />}
/>
</View>
);
}
}
How can I get the name.title?
Thanks
And here is the json data from randomuser.me
{"results":[{"gender":"female","name":{"title":"miss","first":"abby","last":"perkins"},"location":{"street":"9542 highfield road","city":"ely","state":"herefordshire","postcode":"J9 2ZJ"},"email":"abby.perkins#example.com","login":{"username":"redcat541","password":"1026","salt":"LIsOByBg","md5":"2890bf50a87289f7f3664840e2c47fe3","sha1":"1944896ba6cc78ad32dcf927dc5c9226d2f9e050","sha256":"9013be19c91195788009cc545f8a2be4494687dc29b155513022ce9157b73785"},"dob":"1959-05-20 07:03:41","registered":"2006-07-10 01:28:56","phone":"0101 716 4694","cell":"0738-649-138","id":{"name":"NINO","value":"BC 35 80 42 Q"},"picture":{"large":"https://randomuser.me/api/portraits/women/54.jpg","medium":"https://randomuser.me/api/portraits/med/women/54.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/women/54.jpg"},"nat":"GB"}],"info":{"seed":"2e632bbc13c85cb2","results":1,"page":1,"version":"1.1"}}
when I console.log(data.name) I get this {"title":"miss","first":"abby","last":"perkins"} and so on on every Iteration i get different names. So i guess there is no need in data[0] - it looks like everything is ok with getting the proper data object. just need to access data.name.title but no luck with it. Sorry, it pretty confusing for me this time as every prev time there were no problems with any json obj or array
This is caused by the constructor, but I don't know why.
Just pass an empty array and it will work.
this.state = {
dataSource: ds.cloneWithRows([])
};
You can do this too:
this.state = {
dataSource: ds.cloneWithRows([{name: "Ahmed"}])
};
See here for more information:
https://facebook.github.io/react-native/docs/listviewdatasource.html#clonewithrows
Its because your {data.name.title} is directly in view tag. Place that in <Text> component like this:
<ListView
dataSource={this.state.dataSource}
renderRow={(data) =>
<View>
<Text>
{data.phone}
</Text>
<Text>
{data.name.title}
</Text>
</View>
}
renderSeparator={(sectionId, rowId) => <View key={rowId} style={styles.separator} />}
/>