React-Native Rendering json flatlist - json

I am new to react-native. I'm building up complexity but have gotten stuck on rendering FlatList items from a json list. This was working fine for ListView but not able to figure out what I am missing on FlatList.
import React, { Component } from 'react';
import { ActivityIndicator, ListView, Text, View, StyleSheet,TouchableOpacity, FlatList } from 'react-native';
export default class Movies extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: true
}
}
componentDidMount() {
return fetch('https://gnosisdevelopment.com/office/list.json')
.then((response) => response.json())
.then((responseJson) => {
let data_source = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.setState({
isLoading: false,
dataSource: data_source.cloneWithRows(responseJson.office_staff),
}, function() {
// do something with new state
});
})
.catch((error) => {
console.error(error);
});
}
render() {
if (this.state.isLoading) {
return (
<View style={{flex: 1, paddingTop: 20}}>
<ActivityIndicator />
</View>
);
}
return (
<View style={styles.container}>
<FlatList
data={this.state.dataSource}
renderItem={({item}) =>
<Text style={styles.touchButtonText}>{item.staff_name} </Text>
}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex:1,
alignItems: 'center',
alignContent:'center',
flexDirection: 'row',
flexWrap:'wrap',
justifyContent:'center',
},
touchButton:{
alignSelf:'center',
backgroundColor:'#2980b9',
paddingVertical: 25,
width:295,
margin:15,
},
touchButtonText:{
textAlign:'center',
color:'#ffffff',
fontWeight:'bold'
},
})
The text field will be in a touchable and I'll be adding function to the buttons but I wanted to get the listing correct first.
Any suggestions are welcome. Thanks for the help :)
https://gnosisdevelopment.com/office/list.json
{
"title": "Welcome to our office",
"description": "Your smart office assistant",
"office_staff": [
{ "staff_name": "Dr. Bob"},
{ "staff_name": "Dr. Xavior"},
{ "staff_name": "Dr. Sanchez"},
{ "staff_name": "Dr. Robert"},
{ "staff_name": "Dr. Albert"}
]
}
UPDATE with new datasource load:
import React, { Component } from 'react';
import { ActivityIndicator, ListView, Text, View, StyleSheet,TouchableOpacity, FlatList } from 'react-native';
export default class Office extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
dataSource: [],
}
}
componentDidMount() {
return fetch('https://gnosisdevelopment.com/office/list.json')
.then((response) => response.json())
.then((responseJson) => {
// just setState here e.g.
this.setState({ dataSource: responseJson.office_staff, isLoading:false,});
})
.catch((error) => {
console.error(error);
});
}
render() {
if (this.state.isLoading) {
return (
<View style={{flex: 1, paddingTop: 20}}>
<ActivityIndicator />
</View>
);
}
return (
<View style={styles.container}>
<FlatList
data={this.state.dataSource}
renderItem={({item}) =><Text style={styles.touchButtonText}>{item.staff_name}</Text>
}
keyExtractor={(item, index) => index}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex:1,
alignItems: 'center',
alignContent:'center',
flexDirection: 'row',
flexWrap:'wrap',
justifyContent:'center',
},
touchButton:{
alignSelf:'center',
backgroundColor:'#2980b9',
paddingVertical: 25,
width:295,
margin:15,
},
touchButtonText:{
textAlign:'center',
color:'#ffffff',
fontWeight:'bold'
},
})
Final working version:
import React, { Component } from 'react';
import { ActivityIndicator, Text, View, StyleSheet,TouchableOpacity, FlatList } from 'react-native';
export default class Office extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
dataSource: [],
}
}
componentDidMount() {
return fetch('https://gnosisdevelopment.com/office/list.json')
.then((response) => response.json())
.then((responseJson) => {
// just setState here e.g.
this.setState({ dataSource: responseJson.office_staff,isLoading: false });
})
.catch((error) => {
console.error(error);
});
}
render() {
if (this.state.isLoading) {
return (
<View style={{flex: 1, paddingTop: 20}}>
<ActivityIndicator />
</View>
);
}
return (
<View style={styles.container}>
<FlatList
data={this.state.dataSource}
renderItem={({item}) =><Text>{item.staff_name}</Text>}
keyExtractor={(item, index) => index}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex:1,
alignItems: 'center',
alignContent:'center',
flexDirection: 'row',
flexWrap:'wrap',
justifyContent:'center',
},
touchButton:{
alignSelf:'center',
backgroundColor:'#2980b9',
paddingVertical: 25,
width:295,
margin:15,
},
touchButtonText:{
textAlign:'center',
color:'#ffffff',
fontWeight:'bold'
},
})

You don't need to provide a dataSource like that.
constructor(props) {
super(props);
this.state = {
isLoading: true,
dataSource: [],
}
}
componentDidMount() {
return fetch('https://gnosisdevelopment.com/office/list.json')
.then((response) => response.json())
.then((responseJson) => {
// just setState here e.g.
this.setState({
dataSource: responseJson.office_staff,
isLoading: false,
});
})
.catch((error) => {
console.error(error);
});
}

Related

React-Native Download JSON and Display

I am trying to download a json file and display them. But the activity state of isLoading is continuous to be true. I cannot see the data. How do I know if the json was even downloaded ? I have tried other tutorials but still cannot get this going. Where did I do wrong ?
export default class CategoryScreen extends Component {
constructor(props) {
super(props)
this.state = {
isLoading: true,
dataSource: null,
}
}
componentDidMount(){
return fetch('https://reactnative.dev/movies.json')
.then((response) => response.json() )
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson.movies,
})
})
.catch((error) => {
console.log(error);
});
}
render() {
if (this.state.isLoading) {
return (
<View>
<ActivityIndicator />
</View>
)
} else {
let movies = this.state.dataSource.map((val, key) => {
return <View key={key} style={styles.item}>
<Text>{val.title}</Text>
</View>
});
return (
<View style={styles.container}>
{movies}
</View>
);
}
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
// flexDirection: 'column',
// color: '#ffffff',
justifyContent: 'center',
color: 'white',
backgroundColor: '#212121',
},
});

How to present XML in a Flat List react native

I have a React Native application and I want to:
Fetch data in a XML format from here
Translate it to JSON using react-native-xml2js
Display the JSON data in a FlatList
Here's my source code
import React, { useEffect, useState } from 'react';
import { SafeAreaView, FlatList, Text, View } from 'react-native';
import {parseString} from 'xml2js'
export default function App() {
const [isLoading, setLoading] = useState(true);
const [data, setData] = useState([]);
console.log(data);
useEffect(() => {
var url = "http://www.xmltv.co.uk/feed/9437"
fetch(url)
.then((response) => response.text())
.then((responseText) => {
parseString(responseText, function (err, result) {
console.log(result);
// Where do I set data? setData(responseText);
return result;
});
this.setState({
datasource : result
})
})
.catch((error) => {
console.log('Error fetching the feed: ', error);
})
.finally(() => setLoading(false));
});
return (
<SafeAreaView style={{ flex: 1, padding: 24 }}>
{isLoading ? <Text>Loading...</Text> :
( <View style={{ flex: 1, flexDirection: 'column', justifyContent: 'space-between'}}>
<FlatList
data={data.channel}
keyExtractor={({ id }, index) => id}
renderItem={({ item }) => (
<Text>{item.display-name}</Text>
)}
/>
</View>
)}
</SafeAreaView>
);
}
Here's a snippet of the JSON that's rendered using console.log(result)
Object {
"tv": Object {
"$": Object {
"generator-info-name": "xmltv.co.uk",
"source-info-name": "xmltv.co.uk",
},
"channel": Array [
Object {
"$": Object {
"id": "1475611020f8d0be2662c20838ddc555",
},
"display-name": Array [
"AMC from BT",
],
"icon": Array [
Object {
"$": Object {
"src": "/images/channels/1475611020f8d0be2662c20838ddc555.png",
},
},
],
},
}
But I'm unsure as to how I pull it into my flat list. Any help would be hugely appreciated! Thanks.
Try below code that might help:
import React, {useEffect, useState} from 'react';
import {FlatList, SafeAreaView, Text, View} from 'react-native';
import {parseString} from 'react-native-xml2js';
export default function App() {
const [isLoading, setLoading] = useState(true);
const [data, setData] = useState([]);
useEffect(() => {
var url = 'http://www.xmltv.co.uk/feed/9437';
fetch(url)
.then((response) => response.text())
.then((responseText) => {
parseString(responseText, (_, result) => {
setData(result.tv.channel);
});
})
.catch((error) => {
console.log('Error fetching the feed: ', error);
})
.finally(() => setLoading(false));
}, []);
return (
<SafeAreaView style={{flex: 1, padding: 24}}>
{isLoading ? (
<Text>Loading...</Text>
) : (
<View
style={{
flex: 1,
flexDirection: 'column',
justifyContent: 'space-between',
}}>
<FlatList
data={data ?? []}
keyExtractor={({$: {id}}, index) => id}
renderItem={({item}) => <Text>{item['display-name'][0]}</Text>}
/>
</View>
)}
</SafeAreaView>
);
}

Trying to display JSON data, but JSON Parse Error

I am trying to display JSON data on my screen, the integer 4 to be exact.
But, I am receiving a JSON Parse Error.
I've posted and that works fine as in Webhooksite says it successfully posted. Also, it "gets" fine, but the data doesn't display.
// JSON Data
{
"cheetosamount": 4,
"cookiesvalue": 2
}
export default class ChooseDeliveries extends Component {
constructor(props){
super(props);
this.state = {
isLoading: true,
dataSource: []
}
}
componentDidMount(){
this.handleGetRequest();
}
handleGetRequest() {
fetch ('https://webhook.site/e61dd236-92d5-4b3b-882b-a50d6add6cd3',{
method: 'GET',
})
.then(response => response.json())
.then(responseJson => {
this.setState({
dataSource: responseJson,
isLoading: false,
})
})
.catch(error => {
console.error(error);
});
};
render(){
if(this.state.isLoading){
return(
<View style={{flex: 1, padding: 20}}>
<ActivityIndicator/>
</View>
)
} else {
return(
<View style={{flex: 1, paddingTop:20}}>
<Text>
{this.state.dataSource.cheetosamount}
</Text>
</View>
);
}
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
The code seems ok having a glimpse at it maybe try and wrap the response with a JSON.parse?? That would be
...
this.setState({
dataSource: JSON.parse(responseJson), <-- HERE
isLoading: false,
})
...

What is the best way to construct a dropdown and fetch JSON data dynamically from a URL

My dropdown has three Items ===> Item0,Item1,Item2 .
Every time I select a particular item, I would like to fetch the JSON data and display it on the page (on IOS). I do not understand where exactly to define the onPress event for the Dropdown.
Any help would be appreciated.
const leveldata = [
{ value: 'level1', props: { disabled: true } },
{ value: 'level2' },
{ value: 'level3' },
];class TopScores extends Component {
constructor(props) {
super(props);
this.onChangeText = this.onChangeText.bind(this);
this.state = {
data: [],
};
}
onChangeText() {
if (leveldata.value === 'leve1') {
fetch('url')
.then((response) => response.json())
.then((responseData) => {
this.setState({
newdata: responseData.newdata,
});
})
.done();
} else if (leveldata.value === 'level2') {
fetch('url1')
.then((response) => response.json())
.then((responseData) => {
this.setState({
newdata: responseData.newdata,
});
})
.done();
}
}
render() {
console.log('data:', this.state.data);
return (
<View>
<View style={styles.container1}>
<Image
/* eslint-disable global-require */
source={require('../Images/Top.png')}
/* eslint-enable global-require */
/>
<Text style={styles.Text1}> Top Contenders</Text>
</View>
<View>
<Dropdown
data={leveldata}
label='Level'
onChangeText={this.onChangeText}
/>
</View>
</View>
);
}
}
If I remember correctly you need to add the onChangeText prop.
import React, { Component } from 'react';
import {
Text,
View,
StyleSheet,
Image
} from 'react-native';
import { Dropdown } from 'react-native-material-dropdown';
const leveldata = [
{ value: 'level1', props: { disabled: true } },
{ value: 'level2' },
{ value: 'level3' }
];
class TopScores extends Component {
constructor(props) {
super(props);
this.onChangeText = this.onChangeText.bind(this);
this.state = {
data: []
};
}
onChangeText(text) {
if(text === 'leve1'){
fetch('url')
.then((response) => response.json())
.then((responseData) => {
this.setState({
newdata: responseData.newdata,
});
})
.done();
}
}
render() {
return (
<View>
<Dropdown
data={leveldata}
label='Level'
onChangeText={this.onChangeText} />
</View>
);
}
}

Flatview returns only blank lines

I'm trying to connect a react-native program with some data from our SQL Server. Here is the Json string that our link returns:
[{"Item_ID":2,"first_name":"steve","last_name":"jones","phone":"510-712-1822","email":"sjones#waltersandwolf.com","company":"Glass"},{"Item_ID":4,"first_name":"Tina","last_name":"Wills","phone":"510-222-7788","email":"twills#waltersandwolf.com","company":"Glass","notes":"","json":"{fname: \"Tina\", lname: \"Wills\", phone: \"510-222-7788\", email: \"twills#waltersandwolf.com\", company: \"Glass\", project: \"Portal\"}"},{"Item_ID":5,"first_name":"Sleepy","last_name":"owl","phone":"555-555-5555","email":"owl#forest.com","company":"Forest","notes":"whoooooo","json":"{first_name:sleepy,last_name:owl, phone:55555555,company:Forest, email: owl, notes:whoooo}"}]
Using this code snippet I've found on the web, I'm trying to just get this to show up in a flatview but it is blank:
import React, { Component } from 'react';
import { AppRegistry, StyleSheet, FlatList, Text, View, Alert, ActivityIndicator, Platform} from 'react-native';
export default class App extends Component {
constructor(props)
{
super(props);
this.state = {
isLoading: true
}
}
componentDidMount() {
return fetch('https://functions-ww.azurewebsites.net/api/SteveListJSON')
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson
}, function() {
// In this block you can do something with new state.
});
})
.catch((error) => {
console.error(error);
});
}
FlatListItemSeparator = () => {
return (
<View
style={{
height: 1,
width: "100%",
backgroundColor: "#607D8B",
}}
/>
);
}
GetFlatListItem (company) {
Alert.alert(company);
}
render() {
if (this.state.isLoading) {
return (
<View style={{flex: 1, paddingTop: 20}}>
<ActivityIndicator />
</View>
);
}
return (
<View style={styles.MainContainer}>
<FlatList
data={ this.state.dataSource }
ItemSeparatorComponent = {this.FlatListItemSeparator}
renderItem={({item}) => <Text style={styles.FlatListItemStyle} onPress={this.GetFlatListItem.bind(this, item.company)} > {item.company} </Text>}
keyExtractor={(item, index) => index.toString()}
/>
</View>
);
}
}
const styles = StyleSheet.create({
MainContainer :{
justifyContent: 'center',
flex:1,
margin: 10,
paddingTop: (Platform.OS === 'ios') ? 20 : 0,
},
FlatListItemStyle: {
padding: 10,
fontSize: 18,
height: 44,
},
});
I would appreciate any help you could provide. I'm new at this so it may be something simple I'm missing...
Url is returning response as string and the datasource you need is an object so before setting the state of datasource change it to an object.
Add this:--
this.setState({
isLoading: false,
dataSource: JSON.parse(responseJson)
}