React-Native: Display JSON Data in ListView - json

I want to display JSON-Data in a ListView. The Problem is, that the JSON data contains Dictionaries.
In one Row I would like to display 'Gattung', 'ab' and 'bis'.
I am not able to display following JSON-Data in a ListView:
[
{
"Gattung": "ICE",
"Zugummer": 26,
"ab": "Regensburg Hbf",
"bis": "Hanau Hbf",
"Wochentag": "Fr",
"Zeitraum": ""
},
{
"Gattung": "ICE",
"Zugummer": 27,
"ab": "Frankfurt(Main)Hbf",
"bis": "Regensburg Hbf",
"Wochentag": "So",
"Zeitraum": ""
},
{
"Gattung": "ICE",
"Zugummer": 28,
"ab": "Regensburg Hbf",
"bis": "Würzburg Hbf",
"Wochentag": "Fr",
"Zeitraum": ""
},
{
"Gattung": "ICE",
"Zugummer": 35,
"ab": "Hamburg Hbf",
"bis": "Puttgarden",
"Wochentag": "tgl.",
"Zeitraum": "25.06. - 04.09."
},
{
"Gattung": "ICE",
"Zugummer": 36,
"ab": "Puttgarden",
"bis": "Hamburg Hbf",
"Wochentag": "tgl.",
"Zeitraum": "25.06. - 04.09."
}
]
This is my code now:
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
var MainView = React.createClass ({
getInitialState() {
return {
jsonURL: 'http://demo.morgenrot-wolf.de/qubidu/test.json',
dataSource: ds.cloneWithRows(['row 1', 'row 2']),
}
},
componentDidMount(){
this.loadJSONData();
},
loadJSONData() {
fetch(this.state.jsonURL, {method: "GET"})
.then((response) => response.json())
.then((responseData) =>
{
for (var i = 0; i < responseData.length; i++)
{
this.setState({ dataSource: this.state.dataSource.cloneWithRows(responseData[i]) });
}
})
.done(() => {
});
},
render() {
return (
<View style={styles.container}>
<ListView
dataSource={this.state.dataSource}
renderRow={(rowData) => <Text>{rowData}</Text>}
/>
</View>
);
}
});

rowData is an object, so renderRow property of your list should look something like
renderRow: function(rowData) {
return (
<View style={styles.row}>
<Text>{rowData.Gattung}</Text>
<Text>{rowData.ab}</Text>
<Text>{rowData.bis}</Text>
</View>
);
}
Also it is bad idea to call setState inside a loop. If reponseData is an array, this.setState({ dataSource: this.state.dataSource.cloneWithRows(responseData)}); should be enough.
Check this sample: https://rnplay.org/apps/4qH1HA

//returning the main view after data loaded successfully
return (
<View style={styles.MainContainer}>
<ListView
dataSource={this.state.dataSource}
renderSeparator= {this.ListViewItemSeparator}
renderRow={(rowData) =>
<View style={{flex:1, flexDirection: 'column'}} >
<TouchableOpacity onPress={this.GetItem.bind(this, rowData.student_name,rowData.student_subject)} >
<Text style={styles.textViewContainer} >{rowData.id}</Text>
<Text style={styles.textViewContainer} >{rowData.student_name}</Text>
<Text style={styles.textViewContainer} >{rowData.student_phone_number}</Text>
<Text style={styles.textViewContainer} >{rowData.student_subject}</Text>
</TouchableOpacity>
</View>
}
/>
</View>
);
}
}
}
const styles = StyleSheet.create({
MainContainer :{
// Setting up View inside content in Vertically center.
justifyContent: 'center',
flex:1,
paddingTop: (Platform.OS === 'ios') ? 20 : 0,
backgroundColor: '#ffffff',
padding: 5,
},
textViewContainer: {
textAlignVertical:'center',
fontSize: 15,
color: '#1c1c1c',
}
});'

Related

How to parse json data in react native

hi I am new to React native development, how to parse following data please help me
here is my code
componentDidMount() {
fetch('https://api.myjson.com/bins/96ebw')
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson.Pharmacy,
},
);
})
.catch((error) => {
console.error(error);
});
}
renderItem(dataSource) {
const { List: list } = this.state.dataSource
const { item } = dataSource;
return (
<View style={styles.itemBlock}>
<View style={styles.itemMeta}>
<Text style={styles.itemName}>{item.RxDrugName}</Text>
<Text style={styles.itemLastMessage}>{item.RxNumber}</Text>
</View>
<View style={styles.footerStyle}>
<View style={{ paddingVertical: 10 }}>
<Text style={styles.status}>{ item.StoreNumber }</Text>
</View>
<View style={{ justifyContent: 'center', alignItems: 'center' }}>
<Image source={require('../assets/right_arrow_blue.png')} />
</View>
</View>
</View>
);
}
json is
[
{
"Pharmacy": {
"Name": "Hillcrest MOB Pharmacy",
"StoreNumber": "254",
"Address": {
"StreetAddress": "50 Hillcrest Medical Blvd Ste 200-1",
"City": "WACO",
"State": "TX",
"Zip": "76712"
},
"IsDefault": false
},
"ReadyForPickups": [
{
"RxDrugName": "Tizanidine HCL 4mg Caps",
"RxNumber": "6000295",
"StoreNumber": "254",
"PatientPay": "15.59"
}
]
},
{
"Pharmacy": {
"Name": "Waco Pharmacy",
"StoreNumber": "251",
"Address": {
"StreetAddress": "1412 N Valley Mills, Suite 116",
"City": "WACO",
"State": "TX",
"Zip": "76710"
},
"IsDefault": false
},
"ReadyForPickups": [
{
"RxDrugName": "Fluoxetine HCL 40mg Caps",
"RxNumber": "6000233",
"StoreNumber": "251",
"PatientPay": "17.3"
}
]
}
]
The problem is that the json response is an array of objects. You need to select the object from the array.
For example, if you want the first item in the array you could do the following
const first = jsonResponse[0]
{
"Pharmacy":{
"Name":"Hillcrest MOB Pharmacy",
"StoreNumber":"254",
"Address":{
"StreetAddress":"50 Hillcrest Medical Blvd Ste 200-1",
"City":"WACO",
"State":"TX",
"Zip":"76712"
},
"IsDefault":false
},
"ReadyForPickups":[
{
"RxDrugName":"Tizanidine HCL 4mg Caps",
"RxNumber":"6000295",
"StoreNumber":"254",
"PatientPay":"15.59"
}
]
}
Now you can try using first.Pharmacy to capture the data from there.
So console.log(first.Pharmacy.Name) should give you Hillcrest MOB Pharmacy
It also looks like you are trying to create and display a list of these Pharmacies. Depending on the number of items you have there are a couple of ways to do that. However, the most performant and easiest is to use a FlatList. This will take care of the view if for any reason that it extends off of the page.
So let's set up the FlatList.
Firstly, import FlatList from react-native.
Secondly change the setState call in your componentDidMount to be
this.setState({
isLoading: false,
dataSource: responseJson
}
Add the following methods
renderItem = ({item, index}) => {
let { Pharmacy, ReadyForPickups } = item;
if(!ReadyForPickups[0]) return null;
let details = ReadyForPickups[0]
return (
<View style={styles.itemBlock}>
<View style={styles.itemMeta}>
<Text style={styles.itemName}>{details.RxDrugName}</Text>
<Text style={styles.itemLastMessage}>{details.RxNumber}</Text>
</View>
<View style={styles.footerStyle}>
<View style={{ paddingVertical: 10 }}>
<Text style={styles.status}>{ details.StoreNumber }</Text>
</View>
<View style={{ justifyContent: 'center', alignItems: 'center' }}>
<Image source={require('../assets/right_arrow_blue.png')} />
</View>
</View>
</View>
);
}
keyExtractor = (item, index) => {
return index.toString();
}
Then your render method should look something like this
render () {
return (
<View style={{flex: 1}}>
<FlatList
data={this.state.dataSource}
keyExtractor={this.keyExtractor}
renderItem={this.renderItem}
/>
</View>
);
}
Then it should look something like this. Obviously the stylings are missing and I used a substitute image. But this should be the idea of what you are looking for.
Hopefully that should be enough to get the data out that you require.
UPDATE
Here is a fully working component that renders a list similar to the one above
import React, { Component } from 'react';
import { View, Text, FlatList, Image } from 'react-native';
import PropTypes from 'prop-types';
// import screens styles
import styles from './styles';
class Pharmacy extends Component {
/**
* Construct component class
* #param {object} props
*/
constructor (props: {}) {
super(props);
this.state = {
isLoading: true,
dataSource: []
};
}
componentDidMount () {
fetch('https://api.myjson.com/bins/96ebw')
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson
});
});
}
renderItem = ({item, index}) => {
let { Pharmacy, ReadyForPickups } = item;
if (!ReadyForPickups[0]) return null;
let details = ReadyForPickups[0];
return (
<View style={styles.itemBlock}>
<View style={styles.itemMeta}>
<Text style={styles.itemName}>{details.RxDrugName}</Text>
<Text style={styles.itemLastMessage}>{details.RxNumber}</Text>
</View>
<View style={styles.footerStyle}>
<View style={{ paddingVertical: 10 }}>
<Text style={styles.status}>{ details.StoreNumber }</Text>
</View>
<View style={{ justifyContent: 'center', alignItems: 'center' }}>
<Image source={{uri: 'https://images.pexels.com/photos/949586/pexels-photo-949586.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500'}}
style={{height: 50, width: 50}}/>
</View>
</View>
</View>
);
}
keyExtractor = (item, index) => {
return index.toString();
}
render () {
return (
<View style={{flex: 1}}>
<FlatList
data={this.state.dataSource}
keyExtractor={this.keyExtractor}
renderItem={this.renderItem}
/>
</View>
);
}
}
export default Pharmacy;
UPDATE 2
After a chat with the original question poster it seems that they want they only want to show the ReadyForPickups items as a single list.
This can be done by performing a map and a reduce on the responseJson so the setState call can be updated to the following
this.setState({
isloading: false,
dataSource: responseJson.map(item => item.ReadyForPickups).reduce((acc, currValue) => { return acc.concat(currValue); }, [])
});
This will group the ReadyForPickup items into one long list as follows:
[
{
"RxDrugName":"Tizanidine HCL 4mg Caps",
"RxNumber":"6000295",
"StoreNumber":"254",
"PatientPay":"15.59"
},
{
"RxDrugName":"Hydroxychloroquine Sulfate 200 Tabs",
"RxNumber":"6000339",
"StoreNumber":"201",
"PatientPay":"16.18"
},
{
"RxDrugName":"Naratriptan HCL 2.5mg Tabs",
"RxNumber":"6000300",
"StoreNumber":"111",
"PatientPay":"39.04"
},
{
"RxDrugName":"Tizanidine HCL 4mg Caps",
"RxNumber":"6000457",
"StoreNumber":"08",
"PatientPay":"15.59"
},
{
"RxDrugName":"Lisinopril 20mg Tabs",
"RxNumber":"6000318",
"StoreNumber":"08",
"PatientPay":"13.46"
},
{
"RxDrugName":"Fluoxetine HCL 40mg Caps",
"RxNumber":"6000233",
"StoreNumber":"251",
"PatientPay":"17.3"
},
{
"RxDrugName":"Tizanidine HCL 4mg Caps",
"RxNumber":"6000222",
"StoreNumber":"232",
"PatientPay":"15.59"
},
{
"RxDrugName":"Memantine HCL 5mg Tabs",
"RxNumber":"6000212",
"StoreNumber":"231",
"PatientPay":"17.99"
},
{
"RxDrugName":"Clonidine HCL 0.1mg Tabs",
"RxNumber":"6000339",
"StoreNumber":"07",
"PatientPay":"12.71"
},
{
"RxDrugName":"Benazepril HCL 5mg Tabs",
"RxNumber":"6000261",
"StoreNumber":"06",
"PatientPay":"13.45"
},
{
"RxDrugName":"Clonidine HCL 0.1mg Tabs",
"RxNumber":"6000524",
"StoreNumber":"02",
"PatientPay":"12.73"
},
{
"RxDrugName":"Timolol Maleate 20mg Tabs",
"RxNumber":"6000771",
"StoreNumber":"02",
"PatientPay":"15.33"
},
{
"RxDrugName":"Benazepril HCL 5mg Tabs",
"RxNumber":"6002370",
"StoreNumber":"01",
"PatientPay":"13.45"
},
{
"RxDrugName":"Eliquis 5mg Tabs",
"RxNumber":"6002609",
"StoreNumber":"01",
"PatientPay":"20.88"
},
{
"RxDrugName":"Atorvastatin Calcium 20mg Tabs",
"RxNumber":"6002602",
"StoreNumber":"01",
"PatientPay":"17.69"
},
{
"RxDrugName ":"Astagraf Xl 0.5mg Cp24",
"RxNumber":"6000232",
"StoreNumber":"278",
"PatientPay":"15.33"
},
{
"RxDrugName":"Ropinirole HCL 0.5mg Tabs",
"RxNumber":"6000067",
"StoreNumber":"112",
"PatientPay":"14.75"
},
{
"RxDrugName":"Ciprofloxacin HCL 0.3% Soln",
"RxNumber":"6000217",
"StoreNumber":"275",
"PatientPay":"55.06"
},
{
"RxDrugName":"Sotalol HCL 240mg Tabs",
"RxNumber":"6000575",
"StoreNumber":"09",
"PatientPay":"17.5"
}
]
To match the new dataSource the renderItem function should be updated so that it will display the list.
renderItem = ({item, index}) => {
return (
<View style={styles.itemBlock}>
<View style={styles.itemMeta}>
<Text style={styles.itemName}>{item.RxDrugName}</Text>
<Text style={styles.itemLastMessage}>{item.RxNumber}</Text>
</View>
<View style={styles.footerStyle}>
<View style={{ paddingVertical: 10 }}>
<Text style={styles.status}>{item.StoreNumber }</Text>
</View>
<View style={{ justifyContent: 'center', alignItems: 'center' }}>
<Image source={require('../assets/right_arrow_blue.png')} />
</View>
</View>
</View>
);
}
Your responseJson is array of JSON object with format:
{
"Pharmacy": {
"Name": "Hillcrest MOB Pharmacy",
"StoreNumber": "254",
"Address": {
"StreetAddress": "50 Hillcrest Medical Blvd Ste 200-1",
"City": "WACO",
"State": "TX",
"Zip": "76712"
},
"IsDefault": false
},
"ReadyForPickups": [
{
"RxDrugName": "Tizanidine HCL 4mg Caps",
"RxNumber": "6000295",
"StoreNumber": "254",
"PatientPay": "15.59"
}
]
}
So you should
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson
}
);
In render(), you can map() each item in dataSource and call renderItem() as your code:
render() {
return (
<View>
{this.state.dataSource.map(item => this.renderItem(item))}
</View>
)
}
And in renderItem(item), item now is a JSON object with above format, you can render it easily.
renderItem(obj) {
const item = (obj.ReadyForPickups || [])[0] || {};
// this will secure your app not crash when item is invalid data.
return (
<View style={styles.itemBlock}>
<View style={styles.itemMeta}>
<Text style={styles.itemName}>{item.RxDrugName}</Text>
<Text style={styles.itemLastMessage}>{item.RxNumber}</Text>
</View>
<View style={styles.footerStyle}>
<View style={{ paddingVertical: 10 }}>
<Text style={styles.status}>{ item.StoreNumber }</Text>
</View>
<View style={{ justifyContent: 'center', alignItems: 'center' }}>
<Image source={require('../assets/right_arrow_blue.png')} />
</View>
</View>
</View>
);
}

React Native render nested Json

After loading a JSON object and adding it to this.state, I am not able to access levels below the first level. Given this JSON file:
{
"ts": 1530703572,
"trend": {
"val": 0,
"text": "gleichbleibend"
},
"baro": 1011.3453734999999,
"temp": {
"out": {
"f": 85.9,
"c": 29.9
}
},
"hum": {
"out": 28
},
"wind": {
"speed": {
"mph": 2,
"kmh": 3.2
},
"avg": {
"mph": 3,
"kmh": 4.8
},
"dir": {
"deg": 192,
"text": "SSW"
}
},
"rain": {
"rate": 0,
"storm": 0,
"day": 0,
"month": 0,
"year": 451.358
},
"et": {
"day": 88,
"month": 81,
"year": 1802
},
"forecast": {
"val": 6,
"rule": 45,
"text": "Zunehmend wolkig bei gleichbleibender Temperatur."
},
"sun": {
"uv": 6.2,
"rad": 779,
"rise": "4:27",
"set": "20:35"
}
}
the following results:
{this.state.weatherList.ts} works: 1530703572
{this.state.weatherList.temp.out.c} "TypeError: Undefined is not an object (Evaluating: 'this.state.weatherList.temp.out')
The Code:
export default class Weather extends React.Component {
constructor(props) {
super(props)
this.state = {
weatherList: []
}
getPlannerData().then(data => {
this.setState({
weatherList: data
})
})
}
return (
<ScrollView>
<View>
<View>
<Text>{this.state.weatherList.temp.out.c}</Text>
</View>
</View>
</ScrollView>
)
}
}
async function getPlannerData() {
let data = await fetchApi('url')
return data
}
async function fetchApi(url) {
try {
let response = await fetch(url)
let responseJson = await response.json()
console.log(responseJson)
return responseJson
} catch (error) {
console.error(error)
return false
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 22
},
sectionHeader: {
paddingTop: 2,
paddingLeft: 10,
paddingRight: 10,
paddingBottom: 2,
fontSize: 14,
fontWeight: 'bold',
backgroundColor: 'rgba(247,247,247,1.0)'
},
item: {
padding: 10,
fontSize: 18,
height: 44
}
})
The question is how I can alter the code, so I can access the nested elements like "temp".
I tried it with renderItem and {this.state.weaetherList.map((item, i) => without success.
Thanks in advance!
Before your weatherList object is set, anything further than one level down your object will result in an error. this.state.weatherList.ts will not give an error, since it will just be undefined before your request is finished.
You could e.g. keep a state variable loading and only render when you request has finished to get around this.
Example
class Weather extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: true,
weatherList: {}
};
getPlannerData().then(data => {
this.setState({
loading: false,
weatherList: data
});
});
}
render() {
const { loading, weatherList } = this.state;
if (loading) {
return null;
}
return (
<ScrollView>
<View>
<View>
<Text>{weatherList.temp.out.c}</Text>
</View>
</View>
</ScrollView>
);
}
}

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

How can I load data from a JSON file which is stored at GitHub in React Native?

I have the following JSON file in my GitHub and want to load it:
{"Cat": [
{"key": "a", "title": "Bangladesh", "image": "https://raw.githubusercontent.com/mudassir21/server/master/img/bangladesh.jpg"},
{"key": "b", "title": "Sports", "image": "https://raw.githubusercontent.com/mudassir21/server/master/img/sports.jpg"},
{"key": "c", "title": "Politics", "image": "https://raw.githubusercontent.com/mudassir21/server/master/img/politics.jpg"},
{"key": "d", "title": "Entertainment", "image": "https://raw.githubusercontent.com/mudassir21/server/master/img/entertainment.png"},
{"key": "e", "title": "Economics", "image": "https://raw.githubusercontent.com/mudassir21/server/master/img/economics.jpg"},
{"key": "f", "title": "Technology", "image": "https://raw.githubusercontent.com/mudassir21/server/master/img/technology.jpg"},
{"key": "g", "title": "Others", "image": "https://raw.githubusercontent.com/mudassir21/server/master/img/m.jpg"}
]}
I tried to use the following code to fetch it:
getMoviesFromApiAsync() {
return fetch('https://raw.githubusercontent.com/mudassir21/server/master/newsCategory.json')
.then((response) => response.json())
.then((responseJson) => {
return responseJson.Cat;
})
.catch((error) => {
console.error(error);
});
}
<FlatList horizontal= {true}
data={this.getMoviesFromApiAsync()}
renderItem={({item}) => (
<TouchableOpacity
style={styles.catOption}
onPress = { ()=> this.setState({ name: item.title })}
>
<Image
style={styles.imgButton}
source={{uri: item.image}}
/>
<Text style={styles.buttonText}>{item.title}</Text>
</TouchableOpacity>
)
}
/>
However, no data is loaded from the JSON file. What's the problem?
As your fetch is triggered when the list is rendered, the result of the fetch is not set. In order to re-render the list with data I would suggest to set the result inside the state of the Component. This will trigger a re-render and you should be able to see the list after the fetch resolves:
class MyComp extends Component {
state = { result: [] }
componentWillMount(){
this.getMoviesFromApiAsync()
}
getMoviesFromApiAsync = () => fetch('https://raw.githubusercontent.com/mudassir21/server/master/newsCategory.json')
.then((response) => response.json())
.then((responseJson) => {
this.setState({ result: responseJson.Cat });
})
.catch((error) => {
console.error(error);
})
render(){
<FlatList data={this.state.result} ... />
}
}
Read this link
Use this code:
import React, { Component } from 'react';
import { ActivityIndicator, ListView, Text, View } from 'react-native';
export default class Movies extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: true
}
}
componentDidMount() {
return fetch('https://facebook.github.io/react-native/movies.json')
.then((response) => response.json())
.then((responseJson) => {
let ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.setState({
isLoading: false,
dataSource: ds.cloneWithRows(responseJson.movies),
}, 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={{flex: 1, paddingTop: 20}}>
<ListView
dataSource={this.state.dataSource}
renderRow={(rowData) => <Text>{rowData.title}, {rowData.releaseYear}</Text>}
/>
</View>
);
}
}

React-Native Rendering json flatlist

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);
});
}