I am currently trying to learn React-Native atm and I am having some trouble displaying out my items in my FlatList.
The below is my code
import React from 'react';
import { FlatList, ActivityIndicator, Text, View } from 'react-native';
export default class FetchExample extends React.Component {
constructor(props){
super(props);
this.state = {
isLoading: true,
dataSource: []
}
}
componentDidMount(){
return fetch('https://api.coindesk.com/v1/bpi/currentprice.json')
.then((res) => res.json())
.then((resJson) => {
console.log('Here are the stuff', resJson.bpi)
this.setState({
isLoading: false,
dataSource: resJson.bpi,
})
})
// catch any potential errors here
.catch((error) =>{
console.log(error)
})
}
render(){
if(this.state.isLoading){
return(
<View style={{flex: 1, padding: 20}}>
<ActivityIndicator />
</View>
);
}
return(
<View style={{flex: 0.5, padding: 20}}>
<Text>{console.log(this.state.dataSource)}</Text>
<Text>Here's some testing text</Text>
<Text>{console.log("This is in this.state.dataSource", this.state.dataSource)}</Text>
{/* <FlatList
data= {this.state.dataSource}
renderItem = {({item}) => <Text>{console.log(item)}</Text>}
/> */}
</View>
)
}
}
Whenever I uncomment the FlatList the simulator will shoot me an error saying "Invariant Violation: Tried to get frame for out of range index NaN"
What am I doing wrong? Atm I am just trying to see what's in item and get an understanding of how to work with Flatlist
here how i do it
<FlatList
data={[this.state.dataSource]}
renderItem={({ item }) => this._renderListItem(item)}
/>
and here the _renderListItem()
_renderListItem(item){
console.log(item)
return(
<View>
<View style={{flexDirection:'row',width:'100%',backgroundColor:'red'}}>
<Text>{item.USD.code}</Text>
<Text>{item.USD.symbol}</Text>
<Text>{item.USD.description}</Text>
</View>
</View>
)
}
and here is the expo link click here you get the idea
and if any questions you have please ask me ...
Related
How can I fetch data from Firebase Realtime Database using the below method?
My Realtime Database:
import React, { useEffect, useState, useContext, } from 'react';
import { View, Text, Image, StyleSheet, ScrollView, SafeAreaView, ActivityIndicator, FlatList, } from 'react-native';
import {firebase} from '../config';
export default function App() {
const [users, setUsers] = useState([]);
const todoRef = firebase.firestore().collection('testing');
useEffect(() => {
todoRef.onSnapshot(
querySnapshot => {
const users = []
querySnapshot.forEach((doc) => {
const { one, two, three, four
} = doc.data()
users.push({
id: doc.id,
one, two, three, four
})
})
setUsers(users)
}
)
}, [])
return (
<View style={{ backgroundColor: theme.viewOne, }}>
{isLoading ? <ActivityIndicator /> : (
<FlatList
ListHeaderComponent={
<Image source={require('./AllImage/qq2.jpg')}
style={{ width: "auto", height: 150, resizeMode: "cover", }} />
}
data={data}
keyExtractor={({ id }, index) => id}
renderItem={({ item }) => (
<View style={styles.container}>
<View style={styles.item}>
<Text style={styles.mainText}>{item.one}</Text>
</View>
<View style={styles.item}>
<Text style={styles.mainText}>{item.two}</Text>
</View>
</View>
)}
/>
)}
</View>
);
};
Rahul for react-native you can implement it like this instead of using async-await.
You need to connect your app to database like this -
import { firebase } from '#react-native-firebase/database';
const reference = firebase
.app()
.database('https://<databaseName>.<region>.firebasedatabase.app/')
.ref('/users/123');
Then you can perform read-write transactions like this -
import database from '#react-native-firebase/database';
database()
.ref('/users/123')
.once('value')
.then(snapshot => {
console.log('User data: ', snapshot.val());
});
The article has a detailed implementation and you can choose to persist data easily as well. Hope it helps!
I am trying to view JSON data downloaded but receiving Unexpected token < in JSON at position 0. The error code is not helping at all. If I access the JSON using browser, I don't see a problem. It somehow giving error during parsing. Can someone give any suggestions ?
export default class CategoryScreen extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
datasource: null,
}
}
componentDidMount(){
return fetch('http://xhunterx.ezyro.com/a-cnn.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 news = this.state.dataSource.map((val, key) => {
return <View key={key} style={styles.item}>
<Text style={styles.item}>{val.title}</Text>
</View>
});
return (
<View>
{news}
</View>
);
}
Issue is in this line
dataSource: responseJson.movies
You are having an array directly in responseJson, not inside movies. Try with
dataSource: responseJson
I want to display a list of places from a online json url.
import React, { Component } from "react";
import {
View,
StyleSheet,
Dimensions,
Image,
StatusBar,
TextInput,
TouchableOpacity,
Text,
Button,
Platform,
Alert,
FlatList,
ActivityIndicator,
} from "react-native";
let url = "https://cz2006api.herokuapp.com/api/getAll";
let url2 = "";
export default class ClinicComponent extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
dataSource: null,
};
}
componentDidMount() {
return fetch("https://cz2006api.herokuapp.com/api/getAll")
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson.data.data,
});
})
.catch((error) => {
console.log(error);
});
}
render() {
if (this.state.isLoading) {
return (
<View style={styles.container}>
<ActivityIndicator />
</View>
);
} else {
let hospitals = this.state.dataSource.map((val, key) => {
return (
<View key={key} style={styles.item}>
<Text>{val.name}</Text>
</View>
);
});
return (
<View style={styles.item}>
{/* <Text>Content Loaded</Text> */}
{hospitals}
</View>
);
}
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
item: {
flex: 1,
alignSelf: "stretch",
margin: 10,
alignItems: "center",
justifyContent: "center",
borderBottomWidth: 1,
borderBottomColor: "#eee",
},
});
Unfortunately when i tried to run this via expo cli I got an error, saying undefined is not an object
enter image description here
Can anyone help me pls!!! I would just like to have a list of hospitals which are scrollable. Thank you!
The URL of the Json is here: https://cz2006api.herokuapp.com/api/getAll
Simply change your initial state to something like this
this.state = {
isLoading: true,
dataSource: [], // <-- here
};
Your problem is you're using dataSource.map but during api calling your dataSource still stay null until it get its response, and null object have no attribute map. That's the cause of your problem.
remove the return in componentDidMount:
componentDidMount() {
fetch("https://cz2006api.herokuapp.com/api/getAll")
.then((response) => response.json())
.then((responseJson) => {
this.setState({
dataSource: responseJson.data.data,
isLoading: false,
});
})
.catch((error) => {
console.log(error);
});
}
I agree with #Nguyễn's suggestion that your initial state should be an array. However the root of the issue seems to be getting the right properties off off your JSON response.
First, you want responseJson.data instead of responseJson.data.data. That gives me an array and shows a long list but the titles are all blank. That's because your response has Name as an uppercase property but you are accessing name. So you need to change that as well.
export default class ClinicComponent extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
dataSource: [],
};
}
componentDidMount() {
return fetch('https://cz2006api.herokuapp.com/api/getAll')
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson.data,
});
})
.catch((error) => {
console.log(error);
});
}
render() {
//console.log(this.state.dataSource?.[0]);
if (this.state.isLoading) {
return (
<View style={styles.container}>
<ActivityIndicator />
</View>
);
} else {
return (
<View style={styles.item}>
{/* <Text>Content Loaded</Text> */}
{this.state.dataSource.map((val, key) => (
<View key={val._id} style={styles.item}>
<Text>{val.Name}</Text>
</View>
))}
</View>
);
}
}
}
You are fetching a huge amount of data and you probably want some sort of pagination with infinite scrolling. It is extremely slow to load due to the huge payload that we are fetching.
You also have double-escape problem in the JSON response inside the geocodingData section. You want to return this data as an object but it is an escaped string with lots of \" instead.
I am a total beginner in React Native programming. I've had a difficulty finding a tutorial explaining how to do this.
I am fetching a bus schedule data from a web API.
I want to do the following.
Store JSON data inside a variable or something.
Run a function on that JSON data to return appropriate bus data
I have two questions regarding this.
How can I store JSON data inside a variable or locally somehow?
If I want to run a JavaScript function on the JSON data, where do I do it? Inside a separate component's render() function?
What I've tried
I declared let jsondata outside of the class.
Inside componentDidMount I stored responseJson to jsondata using an anonymous function. When I console.log it there, it shows the JSON data properly.
However, when I try to {console.log(jsondata)} after Flatlist, it returns undefined while "Hello" logs correctly.
Why is it behaving this way? How can I use the jsondata?
Code
import React from 'react';
import { FlatList, ActivityIndicator, Text, View } from 'react-native';
let jsondata;
export default class FetchExample extends React.Component {
constructor(props){
super(props);
this.state ={ isLoading: true}
}
// make an API call in the beginning
componentDidMount(){
return fetch('https://api.myjson.com/bins/18o9sd')
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson.shosfc.weekday[7]
}, function(){
jsondata = responseJson;
// console.log(jsondata)
});
})
.catch((error) =>{
console.error(error);
});
}
render(){
if(this.state.isLoading){
return(
<View style={{flex: 1, padding: 50}}>
<ActivityIndicator/>
</View>
)
}
return(
<View style={{flex: 1, paddingTop:50}}>
<FlatList
data={this.state.dataSource}
renderItem={({item}) => <Text>{item.min}</Text>}
// keyExtractor={({id}, index) => id}
/>
{console.log(jsondata)}
</View>
);
}
}
How can I store JSON data inside a variable or locally somehow?
You can put it in a state value, and use local storage for storage.
Status value delivery
this.state ={ jsondata:{}}
...
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson.shosfc.weekday[7],
jsondata = responseJson
});
console.log(this.state.jsondata);
}
Store data locally
import {AsyncStorage} from 'react-native';
...
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson.shosfc.weekday[7],
});
AsyncStorage.setItem('jsondata', JSON,stringify(responseJson));
}
If I want to run a JavaScript function on the JSON data, where do I do it? Inside a separate component's render() function?
I find this question difficult to understand. But the answer to this question I understand is that you can declare and use a function outside of JSON.
thisfunc(){
alert("function in Json")
}
...
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson.shosfc.weekday[7],
});
this.thisfunc.bind(this)
}
Add jsonResponse in state try this.
import React from 'react';
import { FlatList, ActivityIndicator, Text, View } from 'react-native';
export default class FetchExample extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
dataSource: [],
apiResponseJson:null
};
}
// make an API call in the beginning
componentDidMount() {
return fetch('https://api.myjson.com/bins/18o9sd')
.then(response => response.json())
.then(responseJson => {
this.setState(
{
isLoading: false,
dataSource: responseJson.shosfc.weekday[7],
apiResponseJson : responseJson.shosfc
},
);
})
.catch(error => {
console.error(error);
});
}
render() {
if (this.state.isLoading) {
return (
<View style={{ flex: 1, padding: 50 }}>
<ActivityIndicator />
</View>
);
}
return (
<View style={{ flex: 1, paddingTop: 50 }}>
<FlatList
data={this.state.dataSource}
renderItem={({ item }) => <Text>{item.min}</Text>}
// keyExtractor={({id}, index) => id}
/>
{console.log(this.state.apiResponseJson)}
</View>
);
}
}
I have React Native project and when i try to build my phone, i'm getting this error message. Warning: Each child in an array or iterator should have a unique "key" prop. But it works on computer emulator.
Here is json data: http://hazir.net/api/match/today
and here is my codes,
import React from 'react';
import { FlatList, ActivityIndicator, Text, View } from 'react-native';
export default class Matches extends React.Component {
constructor(props){
super(props);
this.state ={ isLoading: true}
}
componentDidMount(){
return fetch('http://hazir.net/api/match/today')
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson,
}, function(){
});
})
.catch((error) =>{
console.error(error);
});
}
render(){
if(this.state.isLoading){
return(
<View style={{flex: 1, padding: 20}}>
<ActivityIndicator/>
</View>
)
}
return(
<View style={{flex: 1, paddingTop:20}}>
<FlatList
data={this.state.dataSource}
renderItem={({item}) => <Text>{item.matchId}, {item.matchDate}</Text>}
keyExtractor={({id}, index) => id}
/>
</View>
);
}
}
The easiest solution would be to update your keyExtractor as it appears to not be working. It doesn't look like your data has an id property, however it does have a matchId property. This means you could do something like the following.
<FlatList
...
keyExtractor={({matchId}, index) => matchId.toString()}
/>
Alternatively you could use the index as the key and do this
<FlatList
...
keyExtractor={({matchId}, index) => index.toString()}
/>