I am trying to load a Flat List with some items fetched from firebase. I have been able to validate that I am getting the data from firebase.
After data is fetched I update an state key "isLoading" to false, to show the flatList.
Just to test I have set data as a static set of values, but still it does not render.
Any ideas why?
export default class ListScreen extends Component {
state = {
posts: [],
isLoading: true
}
componentDidMount() {
fetch('https://test.firebaseio.com/posts.json', {
headers: {
'Content-Type': 'application/json'
}
}).then(response => {
return response.json();
})
.then(items => {
this.setState({
posts: items,
isLoading: false
})
}).catch(err => {
alert(JSON.stringify(err));
});
}
render() {
const activityIndicator = <ActivityIndicator />
let list;
if(this.state.isLoading) {
list = activityIndicator
} else {
list = <FlatList style={{flex: 1}} data={[{key: 'a'}, {key: 'b'}]} renderItem={({item}) => {
return <Text>{item.key}</Text>
}} keyExtractor={(item) => { return item.key; }} />
}
return (
<View style={styles.container}>
<Text>Posts</Text>
<Button title="Add Post" onPress={() => {
this.onAddPost();
}} />
<View>{list}</View>
</View>
)
}
onAddPost = () => {
this.props.navigation.navigate('create');
}
}
Just remove style={{flex: 1}} from the FlatList
Related
Hi I need help as to how do i get a specific value from an array in a web service i am using fetch method to get the data.It is in XML i am using a dependency to convert xml data to JSON.
import React from "react";
import {StyleSheet,View,ActivityIndicator,FlatList,Text,TouchableOpacity} from "react-native";
export default class Source extends React.Component {
static navigationOptions = ({ navigation }) => {
return {
title: "Source Listing",
headerStyle: {backgroundColor: "#fff"},
headerTitleStyle: {textAlign: "center",flex: 1}
};
};
constructor(props) {
super(props);
this.state = {
loading: false,
items:[]
};
}
FlatListItemSeparator = () => {
return (
<View style={{
height: .5,
width:"100%",
backgroundColor:"rgba(0,0,0,0.5)",
}}
/>
);
}
renderItem=(data)=>
<TouchableOpacity style={styles.list}>
<Text style={styles.lightText}>{data.item.name}</Text>
<Text style={styles.lightText}>{data.item.email}</Text>
<Text style={styles.lightText}>{data.item.company.name}</Text>
</TouchableOpacity>
render(){
{
if(this.state.loading){
return(
<View style={styles.loader}>
<ActivityIndicator size="large" color="#0c9"/>
</View>
)}}
return(
<View style={styles.container}>
<FlatList
data= {this.state.dataSource}
ItemSeparatorComponent = {this.FlatListItemSeparator}
renderItem= {item=> this.renderItem(item)}
keyExtractor= {item=>item.id.toString()}
/>
</View>
)}
}
const parseString = require('react-native-xml2js').parseString;
fetch('http://192.168.200.133/apptak_service/apptak.asmx/Get_Item_Master')
.then(response => response.text())
.then((response) => {
parseString(response, function (err, result) {
console.log(response)
});
}).catch((err) => {
console.log('fetch', err)
this.fetchdata();
})
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff"
},
loader:{
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#fff"
},
list:{
paddingVertical: 4,
margin: 5,
backgroundColor: "#fff"
}
});
I am pretty new to react native and development in general i would highly apprecitate any help .I need to seprate the elements and display specific elements in the app.
As far as I can tell from your code, you are not passing the fetched data into your state. You're only logging it in the console:
parseString(response, function (err, result) {
console.log(response)
});
I think you should add the following pieces to your component:
1 . First of all set up the function to be called in your constructor, so it can access the state:
constructor(props) {
super(props);
this.state = {
loading: false,
items:[]
};
this.fetchRequest = this.fetchRequest.bind(this)
}
Create the actual function inside render:
fetchRequest() {
fetch('http://192.168.200.133/apptak_service/apptak.asmx/Get_Item_Master')
.then(response => response.text())
.then((response) => {
parseString(response, function (err, result) {
this.setState({ items: response });
});
}).catch((err) => {
console.log('fetch', err)
})
}
You need to call the fetchRequest function. You can do that in a lifecycle method of your component:
componentDidMount() {
fetchRequest();
}
Last thing is to create your Flatlist correctly:
<FlatList
data= {this.state.items}
renderItem={({ item }) => <Item title={item.title} />}
keyExtractor= {item=>item.id.toString()}
/>
Your data source is this.state.items, and not this.state.dataSource.
Unfortunately I have no idea what your data looks like, so I don't know how the keyExtractor and <Item> should be written. What I can tell you is that you will need unique IDs for your items.
You can read more about Flatlist in the React Native docs.
I am Using FireBase as a Database for fetching data in a react-native app using Redux. I want to Show an Activity Indicator until the data is been fetched.
Here is my code Redux :
export function getHome() {
const request = axios({
method: "GET",
url: `${FIREBASEURL}/home.json`
})
.then(response => {
const articles = [];
for (let key in response.data) {
articles.push({
...response.data[key],
id: key
});
}
return articles;
})
.catch(e => {
return false;
});
return {
type: GET_HOME,
payload: request
};
}
Here is my React Native code where data will be shown:
import React, { Component } from "react";
import {
StyleSheet,
View,
Text,
ScrollView,
ActivityIndicator,
TouchableWithoutFeedback,
Image
} from "react-native";
import { connect } from "react-redux";
import { getHome } from "../store/actions/home_actions";
import DemoScreen from "./rn-sound/demo";
class HomeScreen extends Component {
componentDidMount() {
this.props.dispatch(getHome());
}
renderArticle = imgs =>
imgs.articles
? imgs.articles.map((item, i) => (
<TouchableWithoutFeedback
onPress={() => this.props.navigation.navigate(`${item.navigate}`)}
key={i}
>
<View>
<View>
<Image
style={{
height: 220,
width: "100%",
justifyContent: "space-around"
}}
source={{ uri: `${item.image}` }}
resizeMode="cover"
/>
</View>
<View>
<Text >{item.name}</Text>
</View>
<View>
<Text }>{item.tagline}</Text>
</View>
</View>
</TouchableWithoutFeedback>
))
: null;
render() {
return (
<ScrollView}>
{this.renderArticle(this.props.Home)}
</ScrollView>
);
}
}
how to show Activity Indiactor Untill my data from firebase is been Fetched
You can use loading variable in state. You have set false it before fetch command after that set to true. You can see below sample.
constructor(props) {
super(props);
this.state = {
loading: false
};
}
componentDidMount = () => {
this.setState({
loading: true
})
this.props.dispatch(getHome()).then(response=>{
this.setState({
loading: false
})
})
}
render() {
return (
<ScrollView}>
{this.state.loading == false ? (
<View>
{this.renderArticle(this.props.Home)}
</View>
) : (
<ActivityIndicator size="large" />
)}
</ScrollView>
);
}
I'm trying to understand how the management rest in react-native works ... I copy the current situation:
HomeScreen.js
export default class Home extends React.Component {
constructor(props) {
super(props);
this.state = { loading: true };
}
componentDidMount() {
this.handleBackPress();
this.setState({
loading: true,
});
console.log('url');
return fetch('url')
.then(response => response.json())
.then(responseJson => {
this.setState(
{
loading: false,
dataSource: responseJson.response,
},
function() {},
);
})
.catch(error => {
console.error(error);
});
}
render() {
return (
<Container style={styles.container}>
<Content padder>
<Loader loading={this.state.loading} />
<View style={styles.lineStyle} />
//I want to see what's in here
{this.state.dataSource}
<FlatList
data={this.state.dataSource}
renderItem={({ item }) => (
<Text uppercase={false} style={styles.TextStyleWhite}>
{item}
</Text>
)}
keyExtractor={(item, index) => index}
/>
</Content>
</Container>
);
}
}
the url responds with this structure:
and the errors is this:
How can I recover certain values ('Category' and 'Plans') under the keys ORD01, ORD02, ORD03, FAM00, PEN00 ??
Thank's a lot!
export default class FutureLaunches extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
dataSource: null
};
}
componentDidMount() {
return fetch("https://launchlibrary.net/1.4/launch")
.then(response => response.json())
.then(responseJson => {
this.setState({
isLoading: false,
dataSource: responseJson.launches
});
})
.catch(error => {
console.log(error);
});
}
render() {
if (this.state.isLoading) {
return (
<View style={styles.container}>
<ActivityIndicator />
</View>
);
} else {
let launches = this.state.dataSource.map((val, key) => {
return (
<View key={key}>
<Text style={styles.name}>{val.name}</Text>
<Text>{val.net}</Text>
<Text>{val.windowstart}</Text>
<Text>{val.windowend}</Text>
<Text>{val.count}</Text>
</View>
);
});
return (
<View style={styles.container}>
<ScrollView contentContainerStyle={styles.contentContainer}>
{launches}
</ScrollView>
</View>
);
}
}
}
});
The total in the json is higher than the count, the count displays the amount of data sets on the page. How can i be able to change the count thats on the json so it could allow all the data sets from https://launchlibrary.net/1.4/launch, in this case 183 data sets are available.
According to documentation, there is a limit parameter that controls the page size. Setting that parameter in the URL to -1 returns all results:
https://launchlibrary.net/1.4/launch?limit=-1
I'm wondering what is the proper way to this: Currently I have an "item/s" that comes from my database for display, from here I'm trying to send an "item/s" back to my database once a user taps the send button.
With this code, I'm having the following output:
Nodemon example:
console.log example:
Here's my code
export default class Dishes extends Component {
constructor(props) {
super (props)
this.state = {
data: [],
id: [],
price: [],
count: '',
SplOrder: '',
name: '',
menu_price: '',
tbl: this.props.navigation.state.params.tbl,
orderDet: this.props.navigation.state.params.orderDet,
}
}
submit = ({ item, index }) => {
fetch('http://192.168.254.102:3308/SendOrder/Send', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
order_no: this.state.orderDet,
tbl_id: this.state.tbl,
//special_request: this.state.SplOrder,
menu_desc: this.state.name, //item
menu_price: this.state.menu_price, //item
//order_quantity: this.state.count,
})
}).then(res => res.json())
.then((responseJson) => {
Alert.alert(JSON.stringify(responseJson))
console.log(responseJson);
})
.catch(error => console.error('Error:', error))
}
componentDidMount() {
this.fetchData();
}
_renderItem = ({ item, index }) => {
return (
<View>
<Text>Name: { name }</Text>
<Text>Price: ₱{ price }</Text>
<Text>Status: { item.menu_status }</Text>
</View>
)
}
render() {
return (
<View>
<FlatList
data = {this.state.data}
keyExtractor = {(item, index) => index.toString()}
extraData = {this.state}
renderItem = {this._renderItem} />
<View>
<TouchableOpacity
onPress = {(item) => this.submit(item)}>
<Text style = {styles.SendText}>Send Order</Text>
</TouchableOpacity>
</View>
</View>
)
}
}
UI sample: