fetching multiple API requests in componentDidMount() function react native - android

I want to fetch multiple API requests in componentDidMount() function. I have a picker which take items from API call. I have another API which returns a picker value. Now i want to set selected the value received in latter API in the picker. I am trying to fetch both API in componentDidMount function
Here is my code. Please suggest where i am missing.
import React, { Component } from 'react';
import { AppRegistry, StyleSheet, View, Platform, Picker, ActivityIndicator, Button, Alert} from 'react-native';
export default class FirstProject extends Component {
constructor(props)
{
super(props);
this.state = {
isLoading: true,
PickerValueHolder : ''
}
}
componentDidMount() {
const base64 = require('base-64');
// my API which fetches picker items
return fetch('https://reactnativecode.000webhostapp.com/FruitsList.php')
.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);
});
// another api which fetches a particular fruit_id from database which i ave to set selected in picker.
fetch('http://my_api_url', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"fruit_id":"123"
})
}).then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
PickerValueHolder: responseJson,
}, function() {
// In this block you can do something with new state.
});
})
.catch((error) => {
console.error(error);
});
}
GetPickerSelectedItemValue=()=>{
Alert.alert(this.state.PickerValueHolder);
}
render() {
if (this.state.isLoading) {
return (
<View style={{flex: 1, paddingTop: 20}}>
<ActivityIndicator />
</View>
);
}
return (
<View style={styles.MainContainer}>
<Picker
selectedValue={this.state.PickerValueHolder}
onValueChange={(itemValue, itemIndex) => this.setState({PickerValueHolder: itemValue})} >
{ this.state.dataSource.map((item, key)=>(
<Picker.Item label={item.fruit_name} value={item.fruit_name} key={key} />)
)}
</Picker>
<Button title="Click Here To Get Picker Selected Item Value" onPress={ this.GetPickerSelectedItemValue } />
</View>
);
}
}
const styles = StyleSheet.create({
MainContainer :{
justifyContent: 'center',
flex:1,
margin: 10
}
});

As you said in comment, your second API response:
[{"fruit_id": "123","fruit_name":"Strwaberry"}]
So it might work with minor changes:
.then((responseJson) => {
this.setState({
isLoading: false,
PickerValueHolder: responseJson[0].fruit_name,
}, function() {
// In this block you can do something with new state.
});
})

Related

React Native the correct Rating star is not displayed

I dont know why but my Rating stars are not updated even though I have called the method. This is my sample code:
import { Rating } from 'react-native-elements-master';
componentDidMount() {
return this.mediavoti()
}
My costructor:
constructor(props) {
super(props);
this.state = {
Mediaevento: '2'
}
}
and this is my method:
mediavoti() {
return fetch('url',
{
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
Idevento: this.props.navigation.state.params.TiPasso_Idevento,
})
}).then((response) => response.json())
.then((responseJson) => {
this.setState({
Mediaevento: responseJson[0].Media
}, function () {
});
}).catch((error) => {
console.error(error);
});
}
This is my Rating render component:
<Rating
type="star"
fractions={1}
startingValue={parseFloat(this.state.Mediaevento)}
imageSize={40}
onFinishRating={this.voto}
showRating
style={{ paddingVertical: 10 }} />
I dont know why but it always sees that the state.mediaevento value is 2. But if I use console.log in mediavoti() method I can see that the state is changed.
Can you try this.
componentWillMount() {
return this.mediavoti()
}
Instead of componentDidMount()

JSON Listvew react native

i want to display my JSON in a Listview. the problem is i dont know how to use code for display my JSON data
enter image description here
this is my JSON respone. i want to show nama and harga_jual
import React, { Component } from 'react';
import {
StyleSheet,
Text,
AsyncStorage,
Alert,
ListView,
View
} from 'react-native';
import { Actions } from 'react-native-router-flux';
import { Header, Container, Content, Icon, Left, Body, Right, Button, Title, Card, CardItem, Thumbnail} from 'native-base';
export default class Product extends Component {
constructor(props) {
super(props);
var dataSource = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2
});
this.state={
iduser: '',
idgrup_outlet: '',
url:'',
dataSource: new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2,
}),
}
}
async componentWillMount() {
const value = await AsyncStorage.getItem('iduser').then((value) => {
this.setState({
'iduser': value
});
console.log("ID User is : " + this.state.iduser);
})
const value1 = await AsyncStorage.getItem('idgrup_outlet').then((value) => {
this.setState({
'idgrup_outlet': value
});
console.log("ID Group Outlet is : " +(this.state.idgrup_outlet));
})
const value2 = await AsyncStorage.getItem('url').then((value) => {
this.setState({
'url': value
});
console.log("URL is : " + this.state.url);
})
console.log("ID User is : " + this.state.iduser);
let response = await fetch('http://'+this.state.url+'/web_services/list_produk/new.json', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
erzap: {
iduser: this.state.iduser,
idgrup_outlet: this.state.idgrup_outlet,
}
})
});
let responseJson = await response.json();
// console.log(JSON.stringify(responseJson.produks[nama]));
console.log(JSON.stringify(responseJson.produks));
}
render() {
return (
<Container>
<Header style={{backgroundColor: '#03A9F4'}}>
<Left>
<Button transparent>
<Icon name='menu'/>
</Button>
</Left>
</Header>
<Content>
<ListView
dataSource={this.state.dataSource}
renderRow={(rowData) => <Text>{rowData.nama}</Text>}
/>
</Content>
</Container>
);
}
}
const styles = StyleSheet.create({
carditem: {
paddingLeft: 10,
},
});
this my code
What you can do here is to set the state of your dataSource to responseJson in the componentWillMount method. So it would look something like this:
// ... the rest of the code
let responseJson = await response.json();
this.setState({
dataSource: this.state.dataSource.cloneWithRows(responseJson),
});

Google service account authentication from react native

I'd like to use service account authentication within my react native app, in order to let people update a spreadsheet without the need for them to log into their google account.
I'm pretty lost on how to do it, since all frontend code I see is related to traditional oauth2 login.
Any idea?
I finally dropped the idea of service account and used client oauth.
I relied on the following React Native library : https://github.com/joonhocho/react-native-google-sign-in
Here is my authentication service (simplified, redux + redux thunk based):
// <project_folder>/src/services/auth.js
import GoogleSignIn from 'react-native-google-sign-in';
import { store } from '../store';
import auth from '../actions/auth';
export default () => {
GoogleSignIn.configure({
// https://developers.google.com/identity/protocols/googlescopes
scopes: ['https://www.googleapis.com/auth/spreadsheets'],
clientID: 'XXXXXXXXXXXXXXXXX.apps.googleusercontent.com',
}).then(() => {
GoogleSignIn.signInPromise().then((user) => {
store.dispatch(auth(user.accessToken));
}).catch((err) => {
console.log(err);
});
}).catch((err) => {
console.log(err);
});
};
So then I have the user.accessToken in my redux store and can use it elsewhere to create REST requests to the google sheets API.
Here is a simple example of a component that handles the auth and then retrieves some data from the sheet:
// <project_folder>/src/main.js
import React, { Component } from 'react';
import {
ActivityIndicator,
Text,
View,
StyleSheet,
} from 'react-native';
import { connect } from 'react-redux';
import auth from './services/auth';
import Sheet from './services/sheet';
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
});
const sheetId = 'XX-XXXXXX_XXX_XXXXXXXXXXXXXXXXXXXXXX';
class Main extends Component {
constructor(props) {
super(props);
this.state = {
animating: true,
};
}
componentDidMount() {
auth();
}
componentWillUpdate(nextProps) {
if (this.props.token !== nextProps.token) this.setState({ animating: false });
}
componentDidUpdate(nextProps) {
this.sheet = new Sheet(id, this.props.token);
this.sheet.getDoc();
}
render() {
return (
<View style={styles.container}>
<ActivityIndicator
animating={this.state.animating}
style={{ height: 80 }}
size="large"
/>
{!this.state.animating &&
<Text>
{this.props.name}
</Text>
}
</View>
);
}
}
const mapStateToProps = (state) => {
return {
token: state.auth.get('token'),
name: state.sheet.get('name'),
};
};
export default connect(mapStateToProps)(Main);
And here is a basic service to read/write a sheet:
// <project_folder>/services/sheet.js
import { store } from '../store';
import {
nameGet,
valueGet,
valuePost,
}
from '../actions/sheet';
class Sheet {
constructor(id, token) {
this.id = id;
this.token = token;
this.endPoint = `https://sheets.googleapis.com/v4/spreadsheets/${this.id}`;
}
getDoc() {
fetch(`${this.endPoint}?access_token=${this.token}`).then((response) => {
response.json().then((data) => {
console.log(data);
store.dispatch(nameGet(data.properties.title));
});
});
}
getCell(sheet, cell) {
const range = `${sheet}!${cell}`;
fetch(`${this.endPoint}/values/${range}?access_token=${this.token}`)
.then((response) => {
response.json()
.then((data) => {
console.log(data);
store.dispatch(valueGet(data.values[0][0]));
})
.catch((err) => {
console.log(err);
});
})
.catch((err) => {
console.log(err);
});
}
writeCell(sheet, cell, value) {
const range = `${sheet}!${cell}`;
const body = JSON.stringify({ values: [[value]] });
fetch(
`${this.endPoint}/values/${range}?valueInputOption=USER_ENTERED&access_token=${this.token}`,
{
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body,
}
)
.then((response) => {
response.json()
.then((data) => {
console.log(data);
store.dispatch(valuePost('OK'));
})
.catch((err) => {
console.log(err);
});
})
.catch((err) => {
console.log(err);
});
}
}
export default Sheet;
If there is a better way to do, please let me know.
I have no fully idea about this but yes if you can set the sheet permission as public and access from your application it will not ask you authentication.
also you may use below link may help more technical Google Sheets API v4

ReactNative ListView with Json Api

I can't display json data in listview. I get json data in console.log but not in listview isLoading is always on false.
I dont get any errors .catch(error => console.warn("error")).
Result on screen is first View because this.state.isLoading is false.
Here is a code:
import React, { Component } from 'react';
import { AppRegistry, StyleSheet, ListView, Text, View,Image,TouchableHighlight } from 'react-native';
var productArray = [];
class ListViewDemo extends Component {
constructor(props) {
console.warn("constructor");
super(props);
var dataSource = new ListView.DataSource({rowHasChanged:(r1,r2) => r1.guid != r2.guid});
this.state = {
dataSource: dataSource.cloneWithRows(productArray),
isLoading:true
}
}
componentDidMount() {
console.warn("componentDidMount");
this.getTheData(function(json){
productArray = json;
console.warn(productArray);
this.setState = ({
datasource:this.state.dataSource.cloneWithRows(productArray),
isLoading:false
})
}.bind(this));
console.warn("component -> " + this.state.isLoading);
}
getTheData(callback) {
console.warn("callback");
var url = "https://raw.githubusercontent.com/darkarmyIN/React-Native-DynamicListView/master/appledata.json";
fetch(url)
.then(response => response.json())
.then(json => callback(json))
.catch(error => console.warn("error"));
}
renderRow(rowData, sectionID, rowID) {
console.warn("renderRow");
return (
<TouchableHighlight underlayColor='#dddddd' style={{height:44}}>
<View>
<Text style={{fontSize: 20, color: '#000000'}} numberOfLines={1}>{rowData.display_string}</Text>
<Text style={{fontSize: 20, color: '#000000'}} numberOfLines={1}>test</Text>
<View style={{height: 1, backgroundColor: '#dddddd'}}/>
</View>
</TouchableHighlight>
);
}
render() {
console.warn("render" + this.state.isLoading);
var currentView = (this.state.isLoading) ? <View style={{height: 110, backgroundColor: '#dddddd'}} /> : <ListView dataSource={this.state.dataSource} renderRow={this.renderRow.bind(this)} enableEmptySections={true}/>
return(
<View>
{currentView}
</View>
);
}
}
// App registration and rendering
AppRegistry.registerComponent('AwesomeProject', () => ListViewDemo);
I see a couple of mistakes here.
In your componentDidMount, you are setting datasource intead of dataSource:
componentDidMount() {
console.warn("componentDidMount");
this.getTheData(function(json){
productArray = json;
console.warn(productArray);
this.setState = ({
//datasource:this.state.dataSource.cloneWithRows(productArray),
dataSource:this.state.dataSource.cloneWithRows(productArray),
isLoading:false
})
}.bind(this));
console.warn("component -> " + this.state.isLoading);
}
That's why you're not being able to render, because dataSource is never populated. It is just a little spelling mistake.
You are probably not getting into the second then in your getTheData method because you are not returning a Promise:
getTheData(callback) {
console.warn("callback");
var url = "https://raw.githubusercontent.com/darkarmyIN/React-Native-DynamicListView/master/appledata.json";
fetch(url)
//.then(response => response.json())
.then(response => return response.json())
.then(json => callback(json))
.catch(error => console.warn("error"));
}
Your are making a mistake with your setState, your are assigning it instead of calling it:
//this.setState = ({
// datasource:this.state.dataSource.cloneWithRows(productArray),
// isLoading:false
//})
this.setState({
dataSource:this.state.dataSource.cloneWithRows(productArray),
isLoading:false
})
Let me know if it works.
You are setting the function setState instead of calling it
this.setState = ({
datasource:this.state.dataSource.cloneWithRows(productArray),
isLoading:false
})
should be
this.setState({
datasource:this.state.dataSource.cloneWithRows(productArray),
isLoading:false
})

Populate ListView from web service in React Native

I have this piece of react-native code:
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
ToolbarAndroid,
ListView,
Text,
View
} from 'react-native';
let styles = require('./styles/styles');
class Sunshine extends Component {
constructor(props) {
super(props);
this.state = {isLoading: true, jsonData: ''}
}
componentDidMount() {
this.setState({jsonData: this.getMoviesFromApiAsync()})
}
render() {
if(this.state.isLoading != true) {
return (
<View style={styles.container}>
<ToolbarAndroid
style={styles.baseToolbar}
logo={require('./ic_launcher.png')}
title="Sunshine"
titleTextColor="red"/>
<View style={styles.viewcontainer}>
<Text>{this.state.jsonData.city.id}</Text>
<ListView
dataSource={this.state.jsonData.list}
renderRow={(rowData) => <Text>{rowData.dt}</Text>}
/>
</View>
</View>
);
} else {
return (
<View style={styles.container}>
<ToolbarAndroid
style={styles.baseToolbar}
logo={require('./ic_launcher.png')}
title="Sunshine"
titleTextColor="red"/>
<View style={styles.singleviewcontainer}>
<Text>Loading...</Text>
</View>
</View>
);
}
}
getMoviesFromApiAsync() {
return fetch('http://api.openweathermap.org/data/2.5/forecast/daily?q=94043&mode=json&units=metric&cnt=14&APPID=18dcba27e5bca83fe4ec6b8fbeed7827')
.then((response) => response.json())
.then((responseJson) => {
this.setState({isLoading: false, jsonData: responseJson});
console.log(responseJson);
return responseJson;
})
.catch((error) => {
console.error(error);
});
}
}
AppRegistry.registerComponent('Sunshine', () => Sunshine);
What I think it should happen is that when an answer arrives from the server, the list is populated with it's result. But that's not what's going on. Intsead i get this error:
undefined is not an object (evaluating 'allRowIDs.length')
So what exactly am i doing wrong here?
You have to create a ListViewDataSource with the data list.
constructor (props) {
super(props)
this.dataSource = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2
})
}
componentDidMount () {
// You don't need to assign the return value to the state
this.getMoviesFromApiAsync()
}
render () {
// Use the dataSource
const rows = this.dataSource.cloneWithRows(this.state.jsonData.list || [])
...
return (
...
<ListView
dataSource={rows}
/>
)
}
Full docs here.

Categories

Resources