Backand not connecting when using react-native - react-native

I have created a simple object in backand with three fields - admission_no, username and password. When trying with POST method of REST API in backand, data is getting inserted successfully. But, when I am trying with my emulator, it is not getting connected to this object. I tried many things - checking url of the object, setting the security of the object to public, checking anonymous token but none of these fixed my problem.
Am I doing anything wrong? Please check the code and help me out.
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
Image,
TextInput,
ScrollView
} from 'react-native';
import Container from './Container';
import Button from './Button';
import Label from './Label';
import ImageContainer from './ImageContainer';
export default class RegisterView extends Component {
constructor(props) {
super(props)
this.state = {
email: '',
password: '',
admissionNo:'',
}
}
_handleAdd = () => {
try{
if((this.state.email)!=="" && (this.state.password)!=="" &&
(this.state.admissionNo)!=="" ){
const data = {
admission_no: this.state.admissionNo,
username: this.state.email,
password: this.state.password,
}
const json = JSON.stringify(data);
let response =
fetch('https://api.backand.com:443/1/objects/parents', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'AnonymousToken': 'abcdef', //actual token has been given
'Cache-Control': 'no-cache=\"set-cookie\"',
},
body: json
});
if (response.status === 200) {
alert('Success! You may now login');
this.props.navigator.pop();
}
else {
alert(this.state.admissionNo);
}
}
else
{
alert ("Cannot be empty!")
}
}
catch(err){
alert(err);
console.log(err);
}
}
render() {
return (
<ScrollView style={styles.scroll}>
<ImageContainer>
<Image
style={{width:110,height: 110, justifyContent: 'center',
alignItems: 'center'}}
source={require('./Logo.png')}>
</Image>
</ImageContainer>
<Container>
<TextInput
placeholder="Admission No."
style={styles.textInput}
onChangeText={(text) => this.setState({admissionNo:text})}
autoCapitalize="none"
autoCorrect={false}
onSubmitEditing={(event) => {
const{admissionNo}=this.state.admissionNo;
const{onSubmitEditing}=this.props;
if(!admissionNo) return
onSubmitEditing(admissionNo)
this.refs.SecondInput.focus();
}}
/>
<TextInput
placeholder="Username"
style={styles.textInputUsername}
onChangeText={(text) => this.setState({email:text})}
autoCapitalize="none"
autoCorrect={false}
onSubmitEditing={(event) => {
const{email}=this.state.email;
const{onSubmitEditing}=this.props;
if(!email) return
onSubmitEditing(email)
this.refs.SecondInput.focus();
}}
/>
<TextInput
placeholder="Password"
ref='SecondInput'
secureTextEntry={true}
onChangeText={(text) => this.setState({password:text})}
style={styles.textInputPass}
/>
</Container>
<Container>
<Button
label="Create Account"
styles={{button: styles.primaryButton, label:
styles.buttonWhiteText}}
onPress={this._handleAdd}
/>
</Container>
</ScrollView>
);
}
}

Related

How to send bearer token as parameter and retrieve it in another screen in React Native

I want to send bearer token as parameter from one screen and retrieve it another screen and send it too sidebar.
Login.js where i have saved bearer token in const usertoken but can't figure out how to sent it as parameter
import React from 'react';
import {Button,Text,View,Image,TextInput,SafeAreaView,ImageBackground,Alert} from 'react-native';
export default class Login extends React.Component{
constructor(props) {
super(props)
this.state = {
UserName: '',
UserPassword: ''
}
}
UserLoginFunction = () =>{
const { UserName } = this.state ;
const { UserPassword } = this.state ;
fetch('https://api.idepoz.com/ncl/api/login', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
username: UserName,
password: UserPassword
})
}).then((response) => response.json())
.then((responseJson) => {
//console.log(responseJson);
if(responseJson)
{
const usertoken = responseJson.token;
this.props.navigation.navigate({routeName:'QrScan'});
}
else{
Alert.alert(responseJson);
}
}).catch((error) => {
console.error(error);
});
}
}
The following is the screen where i want to retrieve the parameter and navigate it to sidebar
import React from 'react';
import { Container, Header, Title, Drawer, Content, Footer, FooterTab, Button, Left, Right, Body, Text } from 'native-base';
import { Alert } from 'react-native';
import { MaterialIcons } from '#expo/vector-icons';
import { Ionicons } from '#expo/vector-icons';
import SideBar from './components/SideBar';
export default class QrScan extends React.Component{
closeDrawer = () => {
this.drawer._root.close();
}
openDrawer = () => {
this.drawer._root.open();
}
render()
{
return(
<Drawer
ref={(ref) => { this.drawer = ref; }}
content={<SideBar navigator={this.navigator} closeDrawer={this.closeDrawer}/>}
onClose={() => this.closeDrawer()} >
<Container>
<Header>
<Left>
<Button transparent onPress={this.openDrawer.bind(this)}>
<MaterialIcons name="list" size={40} color="#FFFFFF" />
</Button>
</Left>
<Body>
<Title></Title>
</Body>
<Right>
<Button transparent>
<Ionicons name="search" size={40} color="#FFFFFF" onPress={() => Alert.alert('Search Button pressed')} />
</Button>
</Right>
</Header>
<Content>
<Text>
</Text>
</Content>
</Container>
</Drawer>
);
}
}
This is the sidebar.js where i want to retrieve the token and use it to logout
import React from 'react';
import { Text, Alert } from 'react-native';
import { Drawer,Container, Content, Header, Right, Button } from 'native-base';
import { FontAwesome } from '#expo/vector-icons';
export default class SideBar extends React.Component {
render() {
return (
<Container>
<Header>
<Right>
<Button transparent>
<FontAwesome name="close" size={24} color="#FFFFFF" onPress={() => this.props.closeDrawer()} />
</Button>
</Right>
</Header>
<Content>
<Button transparent>
<Text style={{fontSize: 24}}>Log Out</Text>
</Button>
</Content>
</Container>
);
}
}
This is a expo project and i am using react navigation 4.4.3.
you can use redux for sharing data from one component to another
https://react-redux.js.org/introduction/basic-tutorial
I found the answer, In Login.js I stored the bearer token inside UserLoginFunction
UserLoginFunction = () =>{
const { UserName } = this.state ;
const { UserPassword } = this.state ;
fetch('https://api.idepoz.com/ncl/api/login', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
username: UserName,
password: UserPassword
})
}).then((response) => response.json())
.then((responseJson) => {
if(responseJson)
{
this.props.navigation.navigate('QrScan',{usertoken:responseJson.token});
}
else{
Alert.alert(responseJson);
}
}).catch((error) => {
console.error(error);
});
}
In qrscan.js i retrieved the bearer token like this
constructor(props) {
super(props)
this.state = {
token: ''
}
}
componentDidMount(){
this.setState({
token: this.props.navigation.state.params.usertoken,
})
}
Then i send the token again to sidebar like this inside render
render()
{
// const authtoken= this.props.navigation.getParam('usertoken');
//console.log(this.state.token);
return(
<Drawer
ref={(ref) => { this.drawer = ref; }}
content={<SideBar navigator={this.navigator} closeDrawer={this.closeDrawer} usertoken={this.state.token} />}
onClose={() => this.closeDrawer()} >
<Container>
</Container>
</Drawer>
);
}
I retrieved the bearer token in sidebar like this
render() {
console.log(this.props.usertoken);
return ()
}

Possible Unhandled Promise Rejection (id:0) : ReferenceError: Can't find variable TextInputEmail

import React,{Component} from 'react';
import {View,Text,Image,ImageBackground,
TextInput,TouchableOpacity,AsyncStorage,
ActivityIndicator,StatusBar,StyleSheet} from 'react-native';
import {createStackNavigator} from 'react-navigation-stack' ;
import {createAppContainer,createSwitchNavigator} from 'react-navigation';
import AppContainer from '../App'
import Forgot from '../Screens/Forgot' ;
class Home extends Component {
constructor(props) {
super(props);
this.state = {
TextInputEmail: '',
TextInputPassword: '',
};
}
CheckTextInput = async() =>
{
if (this.state.TextInputEmail != '')
{
if(this.state.TextInputPassword != '')
{
// if(userInfo.TextInputEmail === this.state.TextInputEmail &&
// userInfo.TextInputPassword===this.state.TextInputPassword)
fetch('http://104.197.28.169:3000/auth/login?', {
method: 'POST',
body: JSON.stringify({
"email": TextInputEmail,
"password": TextInputPassword
}),
})
.then((response) => response.json())
.then(() => {
this.props.navigation.navigate('drawernavi')
console.log('response object:',responseJson)
})
.catch((error) => {
console.error(error);
throw error;
});
// await AsyncStorage.setItem('isLoggedIn','1');
// this.props.navigation.navigate('drawernavi')
//this.userLogin()
// alert('Legged in')
// this.userLogin();
}
else
alert('Please Enter Password');
} else
alert('Please Enter Email & Password');
}
render(){
return(
<View>
<ImageBackground style={{width:'100%',height:'100%'}}
source={require('../images/login-screen.png')}>
<View style={{flex:.8,alignItems:'center',justifyContent:'center',marginTop:20}}>
<View style={styles.imageView}>
<Image style={styles.logoImg}
source = {require('../images/core-logo.png')}
></Image>
</View>
<TextInput style={{fontSize:15,borderWidth:1,borderRadius:20,paddingLeft:15,width:300,
borderColor:'black',height:40,marginTop:40}}
keyboardType='email-address'
maxLength={32}
placeholder='Email' placeholderTextColor='#a8a8a8'
onChangeText={TextInputEmail => this.setState({ TextInputEmail })}
value= {this.state.TextInputEmail}
underlineColorAndroid="transparent">
</TextInput>
<TextInput style={{width:300,fontSize:15,borderWidth:1,borderRadius:20,paddingLeft:15,
borderColor:'black',marginTop:20,height:40}}
secureTextEntry={true}
maxLength={14}
placeholder='Password' placeholderTextColor='#a8a8a8'
onChangeText={TextInputPassword => this.setState({ TextInputPassword })}
value= {this.state.TextInputPassword}
underlineColorAndroid="transparent">
</TextInput>
<TouchableOpacity
style={{width:300,marginTop:35,paddingTop:10,paddingBottom:10,backgroundColor:'#2F6995',
borderRadius:20,borderWidth: 1,borderColor: '#fff'}}
onPress={this.CheckTextInput}
underlayColor='#fff'>
<Text style={{color:'#fff',textAlign:'center', paddingLeft : 10, paddingRight : 10,fontSize:17}}>LOGIN</Text>
</TouchableOpacity>
<View style={{alignItems:'center',marginTop:30}}>
<TouchableOpacity
onPress={() => this.props.navigation.navigate('forgotstack')} >
<Text style={{fontSize:12.5,color:'black',borderBottomWidth:1}}> Forgot Password ? </Text>
</TouchableOpacity>
</View>
</View>
</ImageBackground>
</View>
);
}
}
i am creating the functionality of login. i got this error while working on it.i am new to this. when i tried to login, the yellow warnings start appearing
i am fetching the data through a node.js api . so it is required that the input field name in api and react is same or it can be different or there is another way, please suggest correct my code if it is wrong
body: JSON.stringify({
"email": TextInputEmail,
"password": TextInputPassword
}),
//Change it to
body: JSON.stringify({
"email": this.state.TextInputEmail,
"password": this.state.TextInputPassword
}),
The problem is if(userInfo.TextInputEmail === this.state.TextInputEmail) in this conditions userInfo is not defined so userInfo.TextInputEmail is not defined .
please check once

Passing data from one component to another in React Native

I am setting Sub Domain URL's for single app. Sub domain name will enter at the first time. it saves to the async storage and need to retrieve it from a common component
Using the const, it's not working properly.
Here is the partially completed code. baseURL and socketURL is needed inside another component function. How can I access these constants from there ?
index_new.js
import * as React from 'react';
import { View } from 'react-native';
import AsyncStorage from '#react-native-community/async-storage';
import Login from "../screens/common/login/login/login";
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
sub_domain: '',
};
}
async getSchoolCode() {
let sub_domain = '';
try {
sub_domain = await AsyncStorage.getItem('SCHOOL_CODE') || ''
} catch (error) {
}
return sub_domain;
};
async setSubdomain() {
const sub_domain = await this.getschoolcode()
await this.setState({ sub_domain })
}
getBaseUrl() {
return `http://${this.state.sub_domain}.vidhyadhan.in:81/`;
}
getSocketIoUrl() {
return `http://${this.state.sub_domain}.vidhyadhan.in:8080/`;
}
async componentDidMount() {
await this.setSubdomain();
}
render() {
const baseUrl = this.getBaseUrl();
const socketIoUrl = this.getSocketIoUrl();
const extraProps = {
baseUrl,
socketIoUrl
}
return (
<View>
<Login {...extraProps} />
</View>
)
}
}
Login.js
import React, { Component } from 'react'
import {
Alert,
Keyboard,
Text,
View,
TextInput,
TouchableHighlight,
Image,
ActivityIndicator,
StatusBar,
} from 'react-native'
import config from "../../../../config";
import styles from './style'
import { Icon } from "react-native-elements";
import Toaster from '../../../../components/toaster'
import AsyncStorage from '#react-native-community/async-storage';
class Login extends Component {
constructor(props) {
super(props);
this.state = {
credentials: {
schoolcode: "",
email: "",
password: "",
},
loading: false,
school_code: '',
};
}
async getschoolcode() {
let school_code = '';
try {
school_code = await AsyncStorage.getItem('SCHOOL_CODE') || ''
} catch (error) {
}
return school_code;
};
updateText(text, field) {
let newCredentials = Object.assign(this.state.credentials);
newCredentials[field] = text;
// setState should be done like this
this.setState({
credentials: newCredentials
})
if(field == 'schoolcode'){
AsyncStorage.setItem('SCHOOL_CODE', text);
this.getschoolcode().then((keyValue) => {
this.state.school_code = keyValue;
console.log(this.state.school_code);
});
}
}
async login() {
Keyboard.dismiss();
let credentials = this.state.credentials;
if (this.state.credentials.schoolcode == '' || this.state.credentials.email == '' || this.state.credentials.password == '') {
Toaster.toast('Please Enter a valid UserName and Password', '#d30000')
} else {
const that = this;
credentials.email = that.state.credentials.email;
this.setState({ loading: !this.state.loading });
const new_url = this.props.baseUrl;
fetch(config.baseURL + 'mobileapi/get_token/?username=' + `${that.state.credentials.email}` + '&password=' + `${that.state.credentials.password}`, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
credentials: credentials,
}),
})
.then((response) => response.json())
.then(responseJson => {
if (responseJson.confirmation === "success") {
AsyncStorage.setItem('USER_ID', responseJson.data.user_id.toString());
this.setState({ loading: !this.state.loading });
setTimeout(() => {
this.props.navigation.navigate("Home")
}, 500);
} else {
this.setState({ loading: !this.state.loading });
setTimeout(() => {
Toaster.toast('Please Enter a valid UserName and Password', '#d30000')
// throw new Error(responseJson.message);
}, 500);
}
})
.catch((err) => {
//stop loading
this.setState({ loading: !this.state.loading });
setTimeout(() => {
if (JSON.stringify(err.message) === JSON.stringify('Network request failed')) {
Toaster.toast('Please check your internet connection or try again later', '#d30000')
}
}, 500);
})
}
}
render() {
const loginText = (this.state.loading) ? 'Loading' : 'Login';
return (
<View style={styles.container}>
<StatusBar backgroundColor="#2383c9"
translucent={true}
hidden={false}/>
<Image source={require('../../../../assets/images/icons/logo.png')}
style={{ width: 99, height: 99, margin: 5, }} />
<Text style={{ fontSize: 20, margin: 20, color: "#ffffff" }}>Vidhyadhan</Text>
<View style={styles.inputContainer}>
<Image style={styles.inputIcon}
source={require('../../../../assets/images/icons/username.png')} />
<TextInput style={styles.inputs}
placeholder="School-Code"
underlineColorAndroid='transparent'
onChangeText={text => {
this.updateText(text, 'schoolcode')
}} value={this.state.schoolcode}
autoCorrect={false}
autoCapitalize={"none"}
/>
</View>
<View style={styles.inputContainer}>
<Image style={styles.inputIcon}
source={require('../../../../assets/images/icons/username.png')} />
<TextInput style={styles.inputs}
placeholder="Username"
keyboardType="email-address"
underlineColorAndroid='transparent'
onChangeText={text => {
this.updateText(text, 'email')
}} value={this.state.email}
autoCorrect={false}
autoCapitalize={"none"}
/>
</View>
<View style={styles.inputContainer}>
<Image style={styles.inputIcon}
source={require('../../../../assets/images/icons/password.png')} />
<TextInput style={styles.inputs}
placeholder="Password"
secureTextEntry={true}
underlineColorAndroid='transparent'
onChangeText={text => {
this.updateText(text, 'password')
}}
value={this.state.password}
autoCorrect={false}
secureTextEntry />
</View>
<TouchableHighlight style={[styles.buttonContainer, styles.loginButton]}
onPress={this.login.bind(this)} >
<View style={{ justifyContent: 'center', flex: 1, flexDirection: 'row' }}>
{this.state.loading === false ?
<Icon name='login' type='entypo' size={16} color='white' /> :
<ActivityIndicator size="small" color="#ffffff" />}
<Text style={styles.loginText}> {loginText} </Text>
</View>
</TouchableHighlight>
</View>
);
}
}
export default Login;
First, You're not setting the state correctly. Then, you're trying to set the state twice.
Here's a better way of doing it:
import * as React from 'react';
import { View } from 'react-native';
import AsyncStorage from '#react-native-community/async-storage';
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
sub_domain: '',
};
}
async getSchoolCode() {
let sub_domain = '';
try {
sub_domain = await AsyncStorage.getItem('sub_domain') || ''
} catch (error) {
}
return sub_domain;
};
async setSubdomain() {
const sub_domain = await this.getschoolcode()
await this.setState({ sub_domain })
}
getBaseUrl() {
return `http://${this.state.sub_domain}.vidhyadhan.in:81/`;
}
getSocketIoUrl() {
return `http://${this.state.sub_domain}.vidhyadhan.in:8080/`;
}
async componentDidMount() {
await this.setSubdomain();
}
render() {
const baseUrl = this.getBaseUrl();
const socketIoUrl = this.getSocketIoUrl();
return (
<View/>
);
}
}
Based on the comments, here's how your render can be:
render() {
const baseUrl = this.getBaseUrl();
const socketIoUrl = this.getSocketIoUrl();
const extraProps = {
baseUrl,
socketIoUrl
}
return (
<View>
<MyFirstComponent {...extraProps} />
<MySecondComponent {...extraProps} />
</View>
)
}
And in your MyFirstComponent, you can either use this.props.baseUrl or this.props.socketIoUrl

How to upload a photo to a backend server along with form data using API?

Here below is my code, I am trying to capture an image and filling the other input field. Once I click on create button, I am calling an api to upload it to the backend server. But how Do I send the file details to backend? I have the working api in postman. And some of the fields I have not included some of the input field code here because the code will be large here.
API takes the following fields in postman
import React, {Component} from 'react';
import {
StyleSheet,
Button,
TextInput,
Text,
TouchableOpacity,
View,
Picker,
Image,
} from 'react-native';
import ImagePicker from 'react-native-image-picker';
export default class CreateStudent extends React.Component {
constructor(props){
super(props);
this.state = {
studentName: '',
email: '',
newPassword: '',
fileShow: '',
faceDetails: '',
school: 1,
}
}
handleEmail = (text) => {
this.setState({ email: text })
}
handlePassword = (text) => {
this.setState({ newPassword: text })
}
handleName = (text) => {
this.setState({ studentName: text })
}
selectImage = () => {
const options = {
quality: 1.0,
maxWidth: 75,
maxHeight: 75
}
ImagePicker.launchCamera(options,(responce)=>{
const fileDetails ={
uri : responce.uri,
name :responce.fileName,
method: 'POST',
width : 50,
height : 50,
path : responce.path,
type : responce.type,
}
this.setState({
fileShow: responce.uri,
faceDetails: fileDetails
})
console.log(this.state.fileShow);
console.log(fileDetails);
})
}
async onCreateStudentPressed() {
try {
let response = await fetch('http://10.0.2.2:5000/api/students/create', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
file: this.state.fileDetails,
email: this.state.email,
password: this.state.newPassword,
phone_number: this.state.phoneNumber,
class: this.state.class,
section: this.state.section,
school: this.state.school,
name: this.state.studentName
})
});
let res = await response.text();
if (response.status >= 200 && response.status < 300) {
//Handle success
let accessToken = res;
console.log(accessToken);
//On success we will store the access_token in the AsyncStorage
//this.storeToken(accessToken);
} else {
//Handle error
let error = res;
throw error;
}
} catch(error) {
this.setState({error: error});
console.log("error " + error);
this.setState({
passwordUpdated: false
})
}
}
render() {
return (
<View>
<View style={styles.formContainer}>
<Text style ={styles.pageTitle} >Create Student</Text>
<View style={styles.Camera}>
<TouchableOpacity onPress={this.selectImage}>
<Text>Take Picture</Text>
</TouchableOpacity>
</View>
{
this.state.fileShow !== '' ?
<View style={styles.showBlack}>
<View style={styles.placeholder}>
<Image key={1} source={{uri: this.state.fileShow}} style={styles.previewImage} />
</View>
</View>
:
null
}
<TextInput
placeholder='Enter Student Name'
placeholderTextColor='#808080'
style ={styles.textInput}
underlineColorAndroid={'transparent'}
onChangeText = {this.handleName}
/>
<TextInput
placeholder='Enter Student Email'
placeholderTextColor='#808080'
style ={styles.textInput}
underlineColorAndroid={'transparent'}
onChangeText = {this.handleEmail}
/>
<TextInput
placeholder='Enter Password'
placeholderTextColor='#808080'
secureTextEntry={true}
style ={styles.textInput}
underlineColorAndroid={'transparent'}
onChangeText = {this.handlePassword}
/>
<Button
onPress={this.onCreateStudentPressed.bind(this)}
style ={styles.loginBtn}
title="Create"
/>
</View>
</View>
);
}
}
There are various ways you can achieve this. I am going to highlight the easiest way for you to do this. I assume you have a storage service such as Amazon S3 where you store the photo. The easiest way is for you to first upload the image to your S3, the response body will include the url to the uploaded photo. Then you can take that url together with your form values and pass them to your backend.
//Example.js
import React, { Component } from 'react';
import {
//Whatever RN Components you need
StyleSheet,
Text,
View,
Alert,
TouchableHighlight,
TextInput,
ActivityIndicator,
ScrollView,
Picker,
Linking,
Image,
} from 'react-native';
import axios from 'axios';
import { RNS3 } from 'react-native-aws3';
import ImagePicker from 'react-native-image-picker';
export default class RegisterScreen extends Component {
state = {
email: '',
password: '',
confirmedPassword: '',
firstName: '',
lastName: '',
avatar: '',
avatarUri: '',
avatarName: '',
avatarType: '',
loading: false,
errorMessage: '',
uploadMessage: ''
}
onRegisterPress = () => {
this.setState({
errorMessage: '',
registerLoading: true,
uploadMessage: 'This may take a while: Uploading your Profile Pic...'
});
const avatarFile = {
uri: this.state.avatarUri,
name: this.state.avatarName,
type: this.state.avatarType
};
const avatarOptions = {
keyPrefix: 'uploads/path/avatar/' + this.state.email + '/' + new Date().getTime(),
bucket: 'your-bucket-s3',
region: 'us-west-2',
accessKey: 'ACCESSKEY',
secretKey: 'SECRETKEY',
successActionStatus: 201
};
RNS3.put(avatarFile, avatarOptions)
.then((response) => {
if (response.status === 201) {
this.setState({ avatar: response.body.postResponse.location });
} else {//handle error}
})
.then(() => {
this.setState({
uploadMessage: 'Creating your profile'
});
const url = 'someremoteurl.com';
const payload = {
email: this.state.email,
password: this.state.password,
password_confirmation: this.state.confirmedPassword,
first_name: this.state.firstName,
last_name: this.state.lastName,
avatar: this.state.avatar,
};
axios.post(url, payload)
.then((r) => {
this.setState({
uploadMessage: '',
loading: false
});
if (r.status === 200) {
//handle success
}
})
.catch(() => {
// handle form submission error
this.setState({
uploadMessage: '',
loading: false,
error: true
});
});
});
}
openMediaLibrary() {
const options = {
title: 'Select Photo',
storageOptions: {
skipBackup: true,
path: 'images'
}
};
ImagePicker.showImagePicker(options, (response) => {
console.log('Response = ', response);
if (response.didCancel) {
console.log('Cancelled selection of image');
} else if (response.error) {
console.log('Image Picker error', response.error)
} else {
this.setState({
avatarUri: response.uri,
avatarName: response.fileName,
avatarType: response.type
});
}
});
}
render() {
return (
<ScrollView style={{ margin: 15 }}>
<View style={styles.formField}>
<Text style={styles.formLabelStyle}> Email</Text>
<TextInput
placeholder='john#yahoo.com'
underlineColorAndroid='transparent'
onChangeText={(email) => this.setState({ email })}
value={this.state.email}
autoCapitalize='none'
/>
</View>
<View style={styles.formField}>
<Text style={styles.formLabelStyle}> Password (minimum of 8 letters)</Text>
<TextInput
placeholder='password'
underlineColorAndroid='transparent'
onChangeText={(password) => this.setState({ password })}
value={this.state.password}
secureTextEntry
autoCorrect={false}
autoCapitalize='none'
/>
</View>
<View style={styles.formField}>
<Text style={styles.formLabelStyle}> Password Confirmation</Text>
<TextInput
placeholder='retype your password'
underlineColorAndroid='transparent'
onChangeText={(confirmedPassword) => this.setState({ confirmedPassword })}
value={this.state.confirmedPassword}
secureTextEntry
autoCorrect={false}
autoCapitalize='none'
/>
</View>
<View style={styles.formField}>
<Text style={styles.formLabelStyle}> First Name</Text>
<TextInput
placeholder='First Name'
underlineColorAndroid='transparent'
onChangeText={(firstName) => this.setState({ firstName })}
value={this.state.firstName}
/>
</View>
<View style={styles.formField}>
<Text style={styles.formLabelStyle}>Last Name</Text>
<TextInput
placeholder='Last Name'
underlineColorAndroid='transparent'
onChangeText={(lastName) => this.setState({ lastName })}
value={this.state.lastName}
/>
</View>
<View>
<View style={{ padding: 10 }}>
{
this.state.avatarUri.length > 0 ?
<Image
source={{ uri: this.state.avatarUri }}
style={{ width: 140, height: 140 }}
/>
: null
}
</View>
<Button
small
backgroundColor='#13CE66'
title={(this.state.avatarUri.length === 0) ?
'Choose Profile Picture' : 'Change Profile Picture'}
onPress={() => this.openMediaLibrary()}
/>
</View>
<Button
large
backgroundColor='#13CE66'
title='Submit'
onPress={() => this.onRegisterPress() }
/>
</ScrollView>
)
}
}
So when you attempt to register this user, the image is first uploaded and the retrieved url is stored in state to be used as part of form params for avatar.
This is easy, the downside is having to wait for upload response before actually having to send your form params
EDIT
If you are not using a 3rd party storage service or if you would rather send the file to your own servers then use FormData():
//OnRegisterPress function should look like this:
onRegisterPress = () => {
let form = new FormData();
form.append('avatar', {
//from openMedia Function, image selected with image-picker
uri: this.state.avatarUri,
name: this.state.avatarName,
type: this.state.avatarType
});
// append your other params such as email, password, name
form.append('email', this.state.email)
form.append('password', this.state.password)
// when you are done appending, use fetch to send the form data as axios seems to be having a bit of issues doing this.
fetch('http://yourapiendpoint', {
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
},
method: 'POST',
body: form
});
}

undefined is not an object( evaluating ''_this.props.navigator.push")

I am trying to navigate to other page when the user login. But i am getting this error and i can't seem to figure out why. I am using working on mac.
I tried using navigatorIOS too, but the problem won't go away. Please help.
import React, { Component } from 'react';
import {AppRegistry,View,Text,Image, StyleSheet,Navigator, AsyncStorage } from 'react-native';
import {
Container,
List,
ListItem,
Content,
Footer,
FooterTab,
Header,
Button,
Icon,
Tabs,
Title,
InputGroup,
Input
} from 'native-base';
import{
Actions,
Scene,
Router
}from 'react-native-router-flux';
import Reg from './Reg'
export default class Log extends Component{
render(){
return(
<Container>
<View style={{alignItems:'center'}}>
<Icon name='ios-contact' style={{fontSize:120}}/>
</View>
<Content style={{flex:1, top:50}}>
<List>
<ListItem>
<InputGroup>
<Icon name='ios-at-outline' style={{color:'#5bc0de'}}/>
<Input
onChangeText={(username) => this.setState({username})}
value={this.state.username} placeholder='Email id' />
</InputGroup>
</ListItem>
<ListItem>
<InputGroup>
<Icon name='ios-lock-outline' style={{color:'#5bc0de'}}/>
<Input onChangeText={(password) => this.setState({password})}
value={this.state.password} placeholder="Password" secureTextEntry />
</InputGroup>
</ListItem>
<Button info style={{alignSelf:'center'}} onPress={this.Log}>
LOGIN
</Button>
</List>
</Content>
</Container>
);
}
constructor(props){
super(props);
this.state = {username: '', password: ''};
console.log();
}
Log = () => {
fetch('http://192.168.0.20:3000/users', {
method : 'POST',
headers: {
'Accept': 'application/json',
'Content-type': 'application/json',
},
body: JSON.stringify({
username: this.state.username,
password: this.state.password,
})
})
.then((response) => response.json())
.then((res) => {
if(res.success=== true){
var username = res.message;
AsyncStorage.setItem('username', username);
this.props.navigator.push({
id: 'Ideas'
});
}else {
alert(res.message);
}
})
.done();
}
}
Could you use the navigate to other page
Actions.()
EX:
Actions.dashboard();
if pass any data
Actions.dashboard({id: 'Ideas'});
import React, { Component } from 'react';
import {AppRegistry,View,Text,Image, StyleSheet,Navigator, AsyncStorage } from 'react-native';
import {
Container,
List,
ListItem,
Content,
Footer,
FooterTab,
Header,
Button,
Icon,
Tabs,
Title,
InputGroup,
Input
} from 'native-base';
import{
Actions,
Scene,
Router
}from 'react-native-router-flux';
import Reg from './Reg'
export default class Log extends Component{
render(){
return(
<Container>
<View style={{alignItems:'center'}}>
<Icon name='ios-contact' style={{fontSize:120}}/>
</View>
<Content style={{flex:1, top:50}}>
<List>
<ListItem>
<InputGroup>
<Icon name='ios-at-outline' style={{color:'#5bc0de'}}/>
<Input
onChangeText={(username) => this.setState({username})}
value={this.state.username} placeholder='Email id' />
</InputGroup>
</ListItem>
<ListItem>
<InputGroup>
<Icon name='ios-lock-outline' style={{color:'#5bc0de'}}/>
<Input onChangeText={(password) => this.setState({password})}
value={this.state.password} placeholder="Password" secureTextEntry />
</InputGroup>
</ListItem>
<Button info style={{alignSelf:'center'}} onPress={this.Log}>
LOGIN
</Button>
</List>
</Content>
</Container>
);
}
constructor(props){
super(props);
this.state = {username: '', password: ''};
console.log();
}
Log = () => {
fetch('http://192.168.0.20:3000/users', {
method : 'POST',
headers: {
'Accept': 'application/json',
'Content-type': 'application/json',
},
body: JSON.stringify({
username: this.state.username,
password: this.state.password,
})
})
.then((response) => response.json())
.then((res) => {
if(res.success=== true){
var username = res.message;
AsyncStorage.setItem('username', username);
this.props.navigator.push({ // Remove this line
id: 'Ideas' // Remove this line
}); // Remove this line
Actions.<pushComponentName>({id: 'Ideas'}) // Add this line
}else {
alert(res.message);
}
})
.done();
}
}