Reputation: 3709
I am making one Register page in my React Native project. In this page, after filling the form when user presses the Register button one POST request is called. While the POST request response takes some time, I want to show Loading in my screen until I get any response from server.
Here's my code-
import React from 'react';
import { StyleSheet, Text, View, ScrollView, TextInput,
Button,
TouchableHighlight,
Image,
Alert, ActivityIndicator } from 'react-native';
class WelcomeScreen extends React.Component {
constructor() {
super();
this.state = {
first_name:'',
last_name:'',
email : '',
mobile: '',
password:'',
confirmPassword:'',
showLoader:false
}
};
showLoader = () => { this.setState({ showLoader:true }); };
hideLoader = () => { this.setState({ showLoader:false }); };
doSignup(){
this.showLoader();
}
updateValue(text, field) {
if(field == 'first_name') {
this.setState({
first_name: text
})
}
else if(field == 'last_name') {
this.setState({
last_name : text
})
}
else if(field == 'email') {
this.setState({
email : text
})
}
else if(field == 'mobile') {
this.setState({
mobile : text
})
}
else if(field == 'password') {
this.setState({
password : text
})
}
else if(field == 'confirmPassword') {
this.setState({
confirmPassword : text
})
}
}
onClickListener = (viewId) => {
Alert.alert("Alert", "Button pressed "+viewId);
}
submit() {
let collection = {}
collection.first_name = this.state.first_name,
collection.last_name = this.state.last_name,
collection.email = this.state.email,
collection.mobile = this.state.mobile
collection.password = this.state.password,
console.log('#HELLO:', collection);
var url = 'my url';
if(collection.first_name != '' && collection.last_name != '' &&
collection.email != '' && collection.mobile != '' &&
collection.password != '') {
if(this.state.password === this.state.confirmPassword) {
fetch(url, {
method: 'POST',
body: JSON.stringify(collection),
headers: new Headers({
'Content-Type' : 'application/json',
'token': 'token'
})
}).then(res => res.json())
.catch(error=> console.error('Error:', error))
.then(response => console.log('Success:', response));
} else {
Alert.alert('Password and Confirm Password didn\'t match');
}
} else {
Alert.alert('Please fill up the required field');
}
}
render() {
return (
<ScrollView keyboardShouldPersistTaps={'handled'}>
<View style={styles.container}>
<View style={styles.inputContainerEmail}>
<Image style={styles.inputIcon} source={{uri: 'https://png.icons8.com/message/ultraviolet/50/3498db'}}/>
<TextInput style={styles.inputs}
placeholder="Email"
keyboardType="email-address"
underlineColorAndroid='transparent'
onChangeText={(text) => this.updateValue(text, 'email')}/>
</View>
<View style={styles.inputContainer}>
<Image style={styles.inputIcon} source={{uri: 'https://png.icons8.com/key-2/ultraviolet/50/3498db'}}/>
<TextInput style={styles.inputs}
placeholder="Password"
secureTextEntry={true}
underlineColorAndroid='transparent'
onChangeText={(text) => this.updateValue(text, 'password')}/>
</View>
<View style={styles.inputContainer}>
<Image style={styles.inputIcon} source={{uri: 'https://png.icons8.com/key-2/ultraviolet/50/3498db'}}/>
<TextInput style={styles.inputs}
placeholder="Confirm Password"
secureTextEntry={true}
underlineColorAndroid='transparent'
onChangeText={(text) => this.updateValue(text, 'confirmPassword')}/>
</View>
<View style={styles.inputContainer}>
<Image style={styles.inputIcon} source={{uri: 'https://img.icons8.com/ultraviolet/40/000000/administrator-male.png'}}/>
<TextInput style={styles.inputs}
placeholder="First Name"
secureTextEntry={true}
underlineColorAndroid='transparent'
onChangeText={(text) => this.updateValue(text, 'first_name')}/>
</View>
<View style={styles.inputContainer}>
<Image style={styles.inputIcon} source={{uri: 'https://img.icons8.com/ultraviolet/40/000000/administrator-male.png'}}/>
<TextInput style={styles.inputs}
placeholder="Last Name"
secureTextEntry={true}
underlineColorAndroid='transparent'
onChangeText={(text) => this.updateValue(text, 'last_name')}/>
</View>
<View style={styles.inputContainer}>
<Image style={styles.inputIcon} source={{uri: 'https://img.icons8.com/ultraviolet/40/000000/phone.png'}}/>
<TextInput style={styles.inputs}
placeholder="Phone No."
secureTextEntry={true}
underlineColorAndroid='transparent'
textContentType='telephoneNumber'
onChangeText={(text) => this.updateValue(text, 'mobile')}/>
</View>
<TouchableHighlight style={[styles.buttonContainer, styles.loginButton]} onPress=
{()=>{this.submit(); this.doSignup;}}>
<Text style={styles.loginText}>Register</Text>
</TouchableHighlight>
<TouchableHighlight style={styles.buttonContainer} onPress={() => this.onClickListener('restore_password')}>
<Text>Forgot your password?</Text>
</TouchableHighlight>
<TouchableHighlight style={styles.buttonContainerRegister} onPress={() => this.onClickListener('register')}>
<Text>Sign In</Text>
</TouchableHighlight>
</View>
<View style={{ position: 'absolute', top:"50%",right: 0, left: 0 }}>
<ActivityIndicator animating={this.state.showLoader} size="large" color="red" />
</View>
</ScrollView>
);
}
}
I have tried the following solution-
Show loader when button is clicked in react native
But none of them worked in my case. I am not understanding why the Loading is not showing after pressing the Register button as the response is taking some time. So, it would be very nice if someone help to find the problem and give advice to solve it.
Upvotes: 1
Views: 2117
Reputation: 1421
You placed the loading view inside the ScrollView, which probably messes up the positioning. Better to wrap the ScrollView in a containing View and place the loading View as a sibling of the ScrollView, show it using conditional rendering.
render() {
return <View style={{flex: 1}}>
<ScrollView style={{flex: 1}}>
{/* contents here */}
</ScrollView>
{
this.state.showLoader && <View style={{ position: 'absolute', top:"50%",right: 0, left: 0 }}>
<ActivityIndicator size="large" color="red" />
</View>
}
</View>;
}
Upvotes: 1