How to parse a JSON Response in React-Native - json

I have a JSON response from Django REST API like this:
[
{"email": "email1#gmail.com", "fullname": "fn1", "id": 1},
{"email": "email2#gmail.com", "fullname": "fn2", "id": 2},
{"email": "email3#gmail.com", "fullname": "fn3", "id": 3},
{"email": "email4#gmail.com", "fullname": "fn4", "id": 4},
{"email": "email5#gmail.com", "fullname": "fn5", "id": 5}
]
And I want to parse it in React native I used this code but it doesn't function for me I don't know why!
I'm a little bit new to this framework
import React , { useEffect, useState } from 'react';
import { View, ScrollView, Text,ActivityIndicator } from 'react-native';
const Information: () => React$Node = () => {
const [isLoading, setLoading] = useState(true);
const [data, setData] = useState([]);
useEffect(() => {
fetch('http://192.168.1.18:8000/api/User')
.then((response) => response.json())
.then((json) => setData(json))
.catch((error) => console.error(error))
.finally(() => setLoading(false));
}, []);
return (
<>
<ScrollView>
<View>
{isLoading ? <ActivityIndicator/> : (
<View
data={data}
renderItem={({ item }) => (
<Text >{item.id},{item.email},{item.fullname}</Text>
)}
/>
)}
</View>
</ScrollView>
</>
);
};
export default Information;

Here you have an example of FlatList:
return (
<SafeAreaView>
<FlatList
data={data}
renderItem={({ item }) => <Text>{item.email} ... and other stuff</Text>}
keyExtractor={item => item.id}
/>
</SafeAreaView>
)

Related

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

How to use json file fetch in react native

How should I use json data in flatlist?
This is the code I have
import React, { Component } from 'react'
import { Text, View, Button, YellowBox, FlatList, Image, ScrollView, Dimensions, TouchableHighlight } from 'react-native'
import Swiper from 'react-native-swiper'
import {styles} from '../style/styles'
class NavtexPage extends Component {
constructor(props) {//function
YellowBox.ignoreWarnings([
'Warning: componentWillReceiveProps is deprecated',
'Warning: componentWillUpdate is deprecated',
]);
super(props);
this.state = {
indexPage: 0,
isLoading: true,
}
}
//fetch API
componentDidMount = () => {
fetch('http://localhost:3000/jsondb/2',
{
method: "GET",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
})//여기까지 fetch : requests
.then((response) => response.json())//fetch : response
.then((responseData) => {
console.log("성공 : ", responseData);
this.setState({
isLoading: false,
data: responseData
})
})
.catch((error) => {
console.error("api error : " + error.message);
});
}
//_renderItem how to json
_renderItem = ({ item, index }) => {
console.log('json : ', item);
}
render() {
return (
<View style={styles.container}>
<View style={{ flex: 0.1, backgroundColor: 'green' }}>
<Text>NAVTEX</Text>
</View>
<View>
<FlatList//i don't know
style={{ flex: 1, marginTop: 50, borderWidth: 1, borderColor: 'red' }}
data={this.state.data}
numColumns={1}
renderItem={this._renderItem}
// keyExtractor={(item, index) => item.no.toString()}
keyExtractor={(item => )}
/>
</View>//help
</View>
);
}
}
export default NavtexPage;
----------------------------ex.json
[
{
"Page1_1" :
[
{
"main_subject" : "asd",
"sub_subject" : "asd",
"mini_subject" : "asd",
"action" : "asd",
"action_img" : "",
"is_ok" : "1",
},
{
"main_subject" : "" ,
"sub_subject" : "",
"action" : "asd",
"action_img" : "",
"is_ok" : "",
}
]
},
{
"Page1_2" :
[
{
"main_subject" : "asd",
"sub_subject" : "asd",
"mini_subject" : "asd",
"action" : "asd",
"action_img" : "",
"is_ok" : "1",
},
{
"main_subject" : "" ,
"sub_subject" : "",
"action" : "Ping to 155.155.1.2 (NAVTEX TX2 at HF Site)",
"action_img" : "",
"is_ok" : "",
}
]
}
]
Firstly, you need to parse the json to array or object,then assign it to your flatlist data
.then((responseData) => {
let result = Json.parse(responseData)
// you data is array,and have page
let curPageData = result.page1_1
this.setState({
isLoading: false,
data: curPageData
})
})
You can try map function also.
sample code:-
this.state.data.map((data) => { //main data array
return(
data.map((insideData) => { //you can access page1_1 ... pages
return(
<Text>{insideData.main_subject}</Text>
.....
)
})
)
})

.map() only displaying the last item from array

I want to use the Citybik.es API (http://api.citybik.es/) to show data on a Leaflet map.
At the moment, the code is only showing the last item from the bikeData.map(), inside the render function.
The console.log(data) is showing every iterated item from the bikeData.map(), but only displaying the last item.
I am looking for something like this.
What am I missing?
The response looks something like this:
{
"networks": [
{
"company": [
"Bike U Sp. z o.o."
],
"href": "/v2/networks/bbbike",
"id": "bbbike",
"location": {
"city": "Bielsko-Bia\u0142a",
"country": "PL",
"latitude": 49.8225,
"longitude": 19.044444
},
"name": "BBBike"
},
{
"company": [
"PBSC",
"Alta Bicycle Share, Inc"
],
"href": "/v2/networks/melbourne-bike-share",
"id": "melbourne-bike-share",
"location": {
"city": "Melbourne",
"country": "AU",
"latitude": -37.814107,
"longitude": 144.96328
},
"name": "Melbourne Bike Share"
}
}
Here's the JavaScript:
import React, { Component } from 'react';
import L from 'leaflet';
import { Map, TileLayer, Marker, Popup } from 'react-leaflet';
// code for map marker icon
var myIcon = L.icon({
iconUrl: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAApCAYAAADAk4LOAAAFgUlEQVR4Aa1XA5BjWRTN2oW17d3YaZtr2962HUzbDNpjszW24mRt28p47v7zq/bXZtrp/lWnXr337j3nPCe85NcypgSFdugCpW5YoDAMRaIMqRi6aKq5E3YqDQO3qAwjVWrD8Ncq/RBpykd8oZUb/kaJutow8r1aP9II0WmLKLIsJyv1w/kqw9Ch2MYdB++12Onxee/QMwvf4/Dk/Lfp/i4nxTXtOoQ4pW5Aj7wpici1A9erdAN2OH64x8OSP9j3Ft3b7aWkTg/Fm91siTra0f9on5sQr9INejH6CUUUpavjFNq1B+Oadhxmnfa8RfEmN8VNAsQhPqF55xHkMzz3jSmChWU6f7/XZKNH+9+hBLOHYozuKQPxyMPUKkrX/K0uWnfFaJGS1QPRtZsOPtr3NsW0uyh6NNCOkU3Yz+bXbT3I8G3xE5EXLXtCXbbqwCO9zPQYPRTZ5vIDXD7U+w7rFDEoUUf7ibHIR4y6bLVPXrz8JVZEql13trxwue/uDivd3fkWRbS6/IA2bID4uk0UpF1N8qLlbBlXs4Ee7HLTfV1j54APvODnSfOWBqtKVvjgLKzF5YdEk5ewRkGlK0i33Eofffc7HT56jD7/6U+qH3Cx7SBLNntH5YIPvODnyfIXZYRVDPqgHtLs5ABHD3YzLuespb7t79FY34DjMwrVrcTuwlT55YMPvOBnRrJ4VXTdNnYug5ucHLBjEpt30701A3Ts+HEa73u6dT3FNWwflY86eMHPk+Yu+i6pzUpRrW7SNDg5JHR4KapmM5Wv2E8Tfcb1HoqqHMHU+uWDD7zg54mz5/2BSnizi9T1Dg4QQXLToGNCkb6tb1NU+QAlGr1++eADrzhn/u8Q2YZhQVlZ5+CAOtqfbhmaUCS1ezNFVm2imDbPmPng5wmz+gwh+oHDce0eUtQ6OGDIyR0uUhUsoO3vfDmmgOezH0mZN59x7MBi++WDL1g/eEiU3avlidO671bkLfwbw5XV2P8Pzo0ydy4t2/0eu33xYSOMOD8hTf4CrBtGMSoXfPLchX+J0ruSePw3LZeK0juPJbYzrhkH0io7B3k164hiGvawhOKMLkrQLyVpZg8rHFW7E2uHOL888IBPlNZ1FPzstSJM694fWr6RwpvcJK60+0HCILTBzZLFNdtAzJaohze60T8qBzyh5ZuOg5e7uwQppofEmf2++DYvmySqGBuKaicF1blQjhuHdvCIMvp8whTTfZzI7RldpwtSzL+F1+wkdZ2TBOW2gIF88PBTzD/gpeREAMEbxnJcaJHNHrpzji0gQCS6hdkEeYt9DF/2qPcEC8RM28Hwmr3sdNyht00byAut2k3gufWNtgtOEOFGUwcXWNDbdNbpgBGxEvKkOQsxivJx33iow0Vw5S6SVTrpVq11ysA2Rp7gTfPfktc6zhtXBBC+adRLshf6sG2RfHPZ5EAc4sVZ83yCN00Fk/4kggu40ZTvIEm5g24qtU4KjBrx/BTTH8ifVASAG7gKrnWxJDcU7x8X6Ecczhm3o6YicvsLXWfh3Ch1W0k8x0nXF+0fFxgt4phz8QvypiwCCFKMqXCnqXExjq10beH+UUA7+nG6mdG/Pu0f3LgFcGrl2s0kNNjpmoJ9o4B29CMO8dMT4Q5ox8uitF6fqsrJOr8qnwNbRzv6hSnG5wP+64C7h9lp30hKNtKdWjtdkbuPA19nJ7Tz3zR/ibgARbhb4AlhavcBebmTHcFl2fvYEnW0ox9xMxKBS8btJ+KiEbq9zA4RthQXDhPa0T9TEe69gWupwc6uBUphquXgf+/FrIjweHQS4/pduMe5ERUMHUd9xv8ZR98CxkS4F2n3EUrUZ10EYNw7BWm9x1GiPssi3GgiGRDKWRYZfXlON+dfNbM+GgIwYdwAAAAASUVORK5CYII=',
iconSize: [25, 41],
iconAnchor: [12.5, 41],
popupAnchor: [0, -41]
});
class App extends Component {
state = {
location: {
lat: 51.505,
lng: -0.09,
},
bikeData: [],
zoom: 2,
}
//lifecycle method to get the bike information
componentDidMount() {
fetch('https://api.citybik.es/v2/networks')
.then(res => res.json())
.then(response => {
const networkData = response.networks;
networkData.map((data) => {
console.log(data)
this.setState({
bikeData: [data]
});
})
})
}
render() {
const position = [this.state.location.lat, this.state.location.lng]
const bikeData = this.state.bikeData;
return (
<Map className="map" center={position} zoom={this.state.zoom}>
<TileLayer
attribution="&copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors"
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
{
bikeData && bikeData.map((data) => {
console.log(data)
return (
<Marker
icon={myIcon}
key={data.id}
position={[data.location.latitude, data.location.longitude]}>
<Popup>
Name: {data.name} <br />
Station Details: {[data.location.city, data.location.country]}
</Popup>
</Marker>
)
})
}
</Map>
)
}
}
ReactDOM.render(<App/>,
document.getElementById('root')
);
You're repeatedly overwriting the bikeData state item:
fetch('https://api.citybik.es/v2/networks')
.then(res => res.json())
.then(response => {
const networkData = response.networks;
networkData.map((data) => {
console.log(data)
this.setState({ // ***
bikeData: [data] // *** Here
}); // ***
})
})
It's not clear why you're using map there at all; certainly, map is the wrong tool if you're not going to return a value from the callback and not going to use the array map creates.
I can't say for sure, but it seems like you just want to use networkData directly:
fetch('https://api.citybik.es/v2/networks')
.then(res => res.json())
.then(response => {
const networkData = response.networks;
this.setState({bikeData: networkData});
})
Note that I'm assuming you want to overwrite bikeData with the result, not add to it.
Or if you want to transform that data in some way, you'd use the result of map:
fetch('https://api.citybik.es/v2/networks')
.then(res => res.json())
.then(response => {
const networkData = response.networks;
this.setState({
bikeData: networkData.map((data) => {
return /*...do something to data...*/;
})
});
})
(Same assumption.)
To add to bikeData, you'd need to use the callback form of setState:
this.setState(({bikeData}) => ({
bikeData: [...bikeData, ...networkData.map((data) => {
return /*...do something to data...*/;
})]
});
Also note that you have an error in your fetch call (you're not alone, a lot of people do this, so many I wrote it up on my anemic little blog): You haven't checked res.ok:
fetch('https://api.citybik.es/v2/networks')
.then(res => { // ***
if (!res.ok) { // ***
throw new Error(res.status); // ***
} // ***
}) // ***
.then(res => res.json())
.then(response => {
// ...
Try this:
componentDidMount() {
fetch('https://api.citybik.es/v2/networks')
.then(res => res.json())
.then(response => {
const networkData = response.networks; //which is currently an array
this.setState({
bikeData: networkData
});
})
}
You are not recommended to do setState inside loop. So do setState outside the loop. Also the way you push data into array isn't correct. Try below solution
const bikeDataArray = this.state.bikeData;
networkData.map(data => {
console.log(data)
bikeDataArray.push(data);
})
this.setState({
bikeData: bikeDataArray
});

Is it possible to have more than one parameters in data for a FlatList?

Like this for example:
<FlatList data={ this.state.foods, this.state.trees }
renderItem={({item}) => <View><Text>{item.food}</Text><Text>{item.tree}</Text></View>
/>
As long as I have the same key (id), is it possible this can work like this?
this.state.foods:
[{
"id": "1",
"food":"chicken",
"cal":"1000",
}]
this.state.trees:
[{
"id": "1",
"tree":"pine",
"size":"10",
}]
EDIT:
render(){
const {trees, foods} = this.state
const combinedArray = trees.map(tree => Object.assign(tree, foods.find(food => food.id == tree.id)));
return(
componentDidUpdate(prevProps, prevState) {
if (!prevState.foods) {
fetch('https://www.example.com/React/food.php')
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
foods: responseJson.map(item => ({ ...item, progress: new Animated.Value(0), unprogress: new Animated.Value(1) }))
}, function() {
});
})
.catch((error) => {
//console.error(error);
});
fetch('https://www.example.com/React/tree.php')
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
trees: responseJson
}, function() {
});
})
.catch((error) => {
//console.error(error);
});
}
}
You need to supply a single array to a Flatlist data.
You can group the objects based on id and use them
const {trees, foods} = this.state
const combinedArray = trees.map(tree => Object.assign(tree, foods.find(food => food.id == tree.id)));
and then use combinedArray in the Flatlist
If your state is undefined or null initially then you need to add
constructor(props) {
super(props)
this.state = {
trees: [],
foods: []
}
}
to your class component.

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