im new to react native so i just can storing data from input text to firebase and making a login form.
i want to make an apps for survey, there a form input for survey data then passing the id survey to the next form ( user form).
I can do that on CI or wordpress, but i cant do that on react native
the flow like this
Survey form --- send the id inserted firebase ---> User form --> Save Final Data
Edited for show my code
Survey Form
import React, { Component } from 'react';
import {
Button,
StyleSheet,
TextInput,
ScrollView,
ActivityIndicator,
View,
Text,
SafeAreaView,
TouchableOpacity
} from 'react-native';
import {Ionicons} from "#expo/vector-icons"
import firebase from 'firebase';
export default class PostScreen extends Component {
constructor() {
super();
this.dbRef = firebase.firestore().collection('surveys');
this.state = {
usia: '',
kab: '',
kec: '',
desa: '',
rw: '',
rt: '',
jekel: '',
tps: '',
isLoading: false
};
}
inputValueUpdate = (val, prop) => {
const state = this.state;
state[prop] = val;
this.setState(state);
}
storesurveys() {
if(this.state.usia === ''){
alert('Masukan usia anda!')
}else {
this.setState({
isLoading: true,
});
this.dbRef.doc(this.state.usia).set({
usia: this.state.usia,
kab: this.state.kab,
kec: this.state.kec,
desa: this.state.desa,
rw: this.state.rw,
rt: this.state.rt,
jekel: this.state.jekel,
tps: this.state.tps,
}).then((res) => {
this.setState({
usia: '',
kab: '',
kec: '',
desa: '',
rw: '',
rt: '',
jekel: '',
tps: '',
isLoading: false,
});
this.props.navigation.navigate('Dummy')
})
.catch((err) => {
console.error("Error found: ", err);
this.setState({
isLoading: false,
});
});
}
}
render() {
if(this.state.isLoading){
return(
<View style={styles.preloader}>
<ActivityIndicator size="large" color="#9E9E9E"/>
</View>
)
}
return (
<SafeAreaView style={styles.container}>
<View style={styles.header}>
<TouchableOpacity onPress={()=> this.props.navigation.goBack()}>
<Ionicons name="md-arrow-back" size={24} color="#D8D9DB"></Ionicons>
</TouchableOpacity>
<TouchableOpacity>
<Text style={{fontWeight:"500"}}>Formulir surveys</Text>
</TouchableOpacity>
</View>
<ScrollView style={styles.inputForm}>
<View style={styles.inputGroup}>
<TextInput
placeholder={'usia'}
value={this.state.usia}
onChangeText={(val) => this.inputValueUpdate(val, 'usia')}
/>
</View>
<View style={styles.inputGroup}>
<TextInput
placeholder={'kab'}
value={this.state.kab}
onChangeText={(val) => this.inputValueUpdate(val, 'kab')}
/>
</View>
<View style={styles.inputGroup}>
<TextInput
placeholder={'kec'}
value={this.state.kec}
onChangeText={(val) => this.inputValueUpdate(val, 'kec')}
/>
</View>
<View style={styles.inputGroup}>
<TextInput
placeholder={'desa'}
value={this.state.desa}
onChangeText={(val) => this.inputValueUpdate(val, 'desa')}
/>
</View>
<View style={styles.inputGroup}>
<TextInput
placeholder={'rw'}
value={this.state.rw}
onChangeText={(val) => this.inputValueUpdate(val, 'rw')}
/>
</View>
<View style={styles.inputGroup}>
<TextInput
placeholder={'rt'}
value={this.state.rt}
onChangeText={(val) => this.inputValueUpdate(val, 'rt')}
/>
</View>
<View style={styles.inputGroup}>
<TextInput
placeholder={'jekel'}
value={this.state.jekel}
onChangeText={(val) => this.inputValueUpdate(val, 'jekel')}
/>
</View>
<View style={styles.inputGroup}>
<TextInput
placeholder={'tps'}
value={this.state.tps}
onChangeText={(val) => this.inputValueUpdate(val, 'tps')}
/>
</View>
<View style={styles.button}>
<Button
title='Add Survey'
onPress={() => this.storesurveys()}
color="#19AC52"
/>
</View>
</ScrollView>
</SafeAreaView>
);
}
}
User Form
NB : i need pass the survey form to my user form with the id inserted from survey
import React, { Component } from 'react';
import {
Button,
StyleSheet,
TextInput,
ScrollView,
ActivityIndicator,
View,
Text,
SafeAreaView,
TouchableOpacity
} from 'react-native';
import {Ionicons} from "#expo/vector-icons"
import firebase from 'firebase';
export default class PostScreen extends Component {
constructor() {
super();
this.dbRef = firebase.firestore().collection('penduduk');
this.state = {
nik: '',
nama: '',
tgl_lahir: '',
usia: '',
jekel: '',
survey: '',
isLoading: false
};
}
inputValueUpdate = (val, prop) => {
const state = this.state;
state[prop] = val;
this.setState(state);
}
storePenduduk() {
if(this.state.nik === ''){
alert('Masukan NIK anda!')
}else if(this.state.nama === ''){
alert('Masukan Nama anda!')
}else {
this.setState({
isLoading: true,
});
this.dbRef.doc(this.state.nik).set({
nik: this.state.nik,
nama: this.state.nama,
tgl_lahir: this.state.tgl_lahir,
usia: this.state.usia,
jekel: this.state.jekel,
survey : this.state.survey,
}).then((res) => {
this.setState({
nik: nik,
nama: '',
tgl_lahir: '',
usia: '',
jekel: '',
survey: '',
isLoading: false,
});
this.props.navigation.navigate('Dummy')
})
.catch((err) => {
console.error("Error found: ", err);
this.setState({
isLoading: false,
});
});
}
}
render() {
if(this.state.isLoading){
return(
<View style={styles.preloader}>
<ActivityIndicator size="large" color="#9E9E9E"/>
</View>
)
}
return (
<SafeAreaView style={styles.container}>
<View style={styles.header}>
<TouchableOpacity onPress={()=> this.props.navigation.goBack()}>
<Ionicons name="md-arrow-back" size={24} color="#D8D9DB"></Ionicons>
</TouchableOpacity>
<TouchableOpacity>
<Text style={{fontWeight:"500"}}>Formulir Penduduk</Text>
</TouchableOpacity>
</View>
<ScrollView style={styles.inputForm}>
<View style={styles.inputGroup}>
<TextInput
placeholder={'nik'}
value={this.state.nik}
onChangeText={(val) => this.inputValueUpdate(val, 'nik')}
/>
</View>
<View style={styles.inputGroup}>
<TextInput
placeholder={'nama'}
value={this.state.nama}
onChangeText={(val) => this.inputValueUpdate(val, 'nama')}
/>
</View>
<View style={styles.inputGroup}>
<TextInput
placeholder={'tgl_lahir'}
value={this.state.tgl_lahir}
onChangeText={(val) => this.inputValueUpdate(val, 'tgl_lahir')}
/>
</View>
<View style={styles.inputGroup}>
<TextInput
placeholder={'usia'}
value={this.state.usia}
onChangeText={(val) => this.inputValueUpdate(val, 'usia')}
/>
</View>
<View style={styles.inputGroup}>
<TextInput
placeholder={'jekel'}
value={this.state.jekel}
onChangeText={(val) => this.inputValueUpdate(val, 'jekel')}
/>
</View>
<View style={styles.inputGroup}>
<TextInput
placeholder={'survey'}
value={this.state.survey}
onChangeText={(val) => this.inputValueUpdate(val, 'survey')}
/>
</View>
<View style={styles.button}>
<Button
title='Add User'
onPress={() => this.storePenduduk()}
color="#19AC52"
/>
</View>
</ScrollView>
</SafeAreaView>
);
}
}
Can someone giving me an example/source code/ documentation to do that?
thank you
First Screen
this.dbRef.doc(this.state.usia).set({
usia: this.state.usia,
kab: this.state.kab,
kec: this.state.kec,
desa: this.state.desa,
rw: this.state.rw,
rt: this.state.rt,
jekel: this.state.jekel,
tps: this.state.tps,
}).then((res) => {
const insertedId = res.id
this.setState({
usia: '',
kab: '',
kec: '',
desa: '',
rw: '',
rt: '',
jekel: '',
tps: '',
isLoading: false,
});
this.props.navigation.navigate('Dummy', {id: insertedId})
})
.catch((err) => {
console.error("Error found: ", err);
this.setState({
isLoading: false,
});
});
Second Screen :
render() {
if(this.state.isLoading){
const text = this.props.navigation.getParam('id', 'new id');
return(
<View style={styles.preloader}>
<ActivityIndicator size="large" color="#9E9E9E"/>
</View>
)
}
Must follow all rules of this answer so you can id on next screen
You can get inserted id after add();
firebase.firestore().collection("SurveyForm").add({
// inserted values
}). then((docRef) => { const insertedId = docRef.id } })
Related
I made a edit screen and trying to update the value of post through navigation v4 by using getParams and set setParams but when I change the old value and click save buttton to save it, it's not updating it and no error is showing either. It's still showing old values. Can someone please help me, below is my code
EditScreen.js
class EditScreen extends Component {
render() {
const { params } = this.props.navigation.state;
return (
<KeyboardAvoidingView
behavior="position"
keyboardVerticalOffset={Platform.OS === "ios" ? 0 : 100}
>
<Image
style={styles.image}
source={this.props.navigation.getParam("image")}
/>
<View style={styles.detailContainer}>
<AppTextInput
value={this.props.navigation.getParam("title")}
onChangeText={(text) =>
this.props.navigation.setParams({ title: text })
}
/>
<AppTextInput
value={this.props.navigation.getParam("des")}
onChangeText={(text) =>
this.props.navigation.setParams({ des: text })
}
/>
</View>
<AppButton
text="Save"
style={styles.button}
onPress={() => {
this.props.navigation.getParam("onEdit");
this.props.navigation.goBack();
}}
/>
</KeyboardAvoidingView>
Home.js
class Home extends Component {
state = {
modal: false,
post: [
{
key: "1",
title: "A Good Boi",
des: "He's a good boi and every one know it.",
image: require("../assets/dog.jpg"),
},
{
key: "2",
title: "John Cena",
des: "As you can see, You can't see me!",
image: require("../assets/cena.jpg"),
},
],
};
onEdit = (data) => {
const newPosts = this.state.post.map((item) => {
if (item.key === data.key) return data;
else return item;
});
this.setState({ post: newPosts, editMode: false });
};
render() {
return (
<Screen style={styles.screen}>
<FlatList
data={this.state.post}
renderItem={({ item }) => (
<>
<TouchableOpacity
activeOpacity={0.7}
onPress={() =>
this.props.navigation.navigate("Edit", {
image: item.image,
title: item.title,
des: item.des,
onEdit: this.onEdit,
})
}
style={styles.Edit}
>
<MaterialCommunityIcons
name="playlist-edit"
color="green"
size={35}
/>
</TouchableOpacity>
<Card onPress={() => this.props.navigation.push("Details", item)}>
<Image style={styles.image} source={item.image} />
<View style={styles.detailContainer}>
<Text style={styles.title} numberOfLines={1}>
{item.title}
</Text>
<Text style={styles.subTitle} numberOfLines={2}>
{item.des}
</Text>
</View>
</Card>
</>
I recommend you to keep the data in the component state:
constructor(props) {
super(props);
// get the data that you need from navigation params
const { key, title, ..} = this.props.navigation.state.params
this.state = {key, title, ..}
}
then :
<AppTextInput
value={this.state.title}
onChangeText={(text) =>
this.setState({ title: text })
}
/>
<AppButton
text="Save"
style={styles.button}
onPress={() => {
this.props.navigation.getParam("onEdit")(this.state);
this.props.navigation.goBack();
}}
/>
Maybe try this:
<AppButton
text="Save"
style={styles.button}
onPress={() => {
this.props.navigation.getParam("onEdit")(this.props.navigation.state.params);
this.props.navigation.goBack();
}}
/>
and:
this.props.navigation.navigate("Edit", {
key: item.key,
image: item.image,
title: item.title,
des: item.des,
onEdit: this.onEdit,
})
I have created a form to upload the image and text field on the home screen but I am facing a problem that it's not updating the array and validation is failing due to that. I think something wrong with my implementation
AddPost.js
const validationSchema = Yup.object({
title: Yup.string().required().min(5).max(15).label("Title"),
des: Yup.string().required().min(15).max(200).label("Description"),
image: Yup.array().required().label("Image"),
});
class AddPost extends Component {
render() {
return (
<Formik
initialValues={{ title: "", des: "", image: [] }}
onSubmit={(values, actions) => {
actions.resetForm();
this.props.addPost(values);
}}
validationSchema={validationSchema}
>
{(value) => (
<View>
<FormImage />
<Text style={styles.error}>
{value.touched.image && value.errors.image}
</Text>
<TextInput
placeholder="Title"
onChangeText={value.handleChange("title")}
style={styles.input}
value={value.values.title}
onBlur={value.handleBlur("title")}
/>
<Text style={styles.error}>
{value.touched.title && value.errors.title}
</Text>
Here is my form field I think everything is right here
home.js
class Home extends Component {
state = {
modal: false,
post: [
{
key: "1",
title: "A Good Boi",
des: "He's a good boi and every one know it.",
image: require("../assets/dog.jpg"),
},
{
key: "2",
title: "John Cena",
des: "As you can see, You can't see me!",
image: require("../assets/cena.jpg"),
},
],
image: null,
};
addPost = (posts) => {
posts.key = Math.random().toString();
this.setState.post((currentPost) => {
return [posts, ...currentPost];
});
this.state.modal();
};
render() {
return (
<Screen style={styles.screen}>
<Modal visible={this.state.modal} animationType="slide">
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View style={styles.modalContainer}>
<AddPost addPost={() => this.addPost} />
</View>
</TouchableWithoutFeedback>
</Modal>
<FlatList
data={this.state.post}
renderItem={({ item }) => (
<>
<Card
title={item.title}
subTitle={item.des}
image={item.image}
onPress={() => this.props.navigation.navigate("Edit", item)}
/>
</>
I think something wrong with the addPost method because I did it before with function base that time I only added text to the list and its worked but in class base I don't know to do it I just try the same way I did in function base
FormImage.js
class FormImage extends Component {
state = {
image: null,
hasCameraPermission: null,
};
async componentDidMount() {
const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL);
this.setState({ hasCameraPermission: status === "granted" });
}
_pickImage = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true,
aspect: [4, 3],
});
if (!result.cancelled) {
this.setState({ image: result.uri });
}
};
render() {
const { image } = this.state;
return (
<TouchableWithoutFeedback onPress={this._pickImage}>
<View style={styles.container}>
{!image && (
<MaterialCommunityIcons
color={colors.medium}
name="camera"
size={40}
/>
)}
{image && <Image style={styles.image} source={{ uri: image }} />}
</View>
</TouchableWithoutFeedback>
);
}
}
after submiting
Iam assuming your addPost function logic is wrong,
Try the below code
addPost = (posts) => {
posts.key = Math.random().toString();
this.setState((prevState) => {
return {...prevState, post: [...prevState.post, ...posts] };
});
this.state.modal();
};
Let me know incase you are getting the same error.
You are not updating images to formik so is normal you get the required error.
First in your AddPost Component pass down formikProps to FormImage component.
return (
<Formik
initialValues={{ title: "", des: "", image: [] }}
onSubmit={(values, actions) => {
// actions.resetForm(); --> comment this
this.props.addPost(values);
}}
validationSchema={validationSchema}
>
{(value) => (
<View>
<FormImage formikProps={value}/>
<Text style={styles.error}>
{value.touched.image && value.errors.image}
</Text>
<TextInput
placeholder="Title"
onChangeText={value.handleChange("title")}
style={styles.input}
value={value.values.title}
onBlur={value.handleBlur("title")}
/>
<Text style={styles.error}>
{value.touched.title && value.errors.title}
</Text>
In FormImage use that formikProps and call setFieldValue("image", result.uri) to update formik value for image.
class FormImage extends Component {
state = {
image: null,
hasCameraPermission: null,
};
async componentDidMount() {
const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL);
this.setState({ hasCameraPermission: status === "granted" });
}
_pickImage = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true,
aspect: [4, 3],
});
if (!result.cancelled) {
this.setState({ image: result.uri });
this.props.formikProps.setFieldValue("image", result.uri);
}
};
render() {
const { image } = this.state;
return (
<TouchableWithoutFeedback onPress={this._pickImage}>
<View style={styles.container}>
{!image && (
<MaterialCommunityIcons
color={colors.medium}
name="camera"
size={40}
/>
)}
{image && <Image style={styles.image} source={{ uri: image }} />}
</View>
</TouchableWithoutFeedback>
);
}
}
In home
addPost = (posts) => {
console.log('add post');
posts.key = Math.random().toString();
this.setState((prevState) => {
return {...prevState, post: [...prevState.post, ...posts], modal:
true };
});
// this.state.modal();
};
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.
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>;
}
I am building a form in a React Native app using Formik.
The form doesn't fire the handleSubmit when I click on the button:
<ButtonLoading
loading={isLoading || isSubmitting}
label="Salvar"
style={styles.button}
onPress={handleSubmit}
/>
Here is my full code for this form:
import React, { Component, Fragment } from 'react';
import { View, ScrollView } from 'react-native';
import { withFormik } from 'formik';
class Form extends Component {
state = {
isCepChecked: false,
isLoading: false,
isNewAddress: true,
};
onChangeCep = () => {
// Not related to the problem
};
render() {
const { isCepChecked, isLoading } = this.state,
{
values,
errors,
touched,
setFieldValue,
setFieldTouched,
handleSubmit,
isSubmitting,
} = this.props;
return (
<View style={styles.container}>
<ScrollView style={styles.formContainer}>
{!isCepChecked ? (
<Fragment>
<View style={styles.lineContent}>
<InputComponent
label="Digite o CEP"
name="nrCepPre"
value={values.nrCepPre}
error={errors.nrCepPre}
touched={touched.nrCepPre}
onTouch={setFieldTouched}
onChange={setFieldValue}
keyboardType="phone-pad"
mask={'[00000]-[000]'}
/>
</View>
<View style={styles.lineContent}>
<ButtonLoading
isLoading={isLoading || isSubmitting}
label="Avançar"
style={styles.button}
onPress={() => this.onChangeCep()}
/>
</View>
</Fragment>
) : (
<Fragment>
<View style={styles.lineContent}>
<InputComponent
label="CEP"
value={values.nrCep}
mask={'[00000]-[000]'}
editable={false}
/>
</View>
<View style={styles.lineContent}>
<InputComponent
label="Identificação"
name="dsEndereco"
value={values.dsEndereco}
error={errors.dsEndereco}
touched={touched.dsEndereco}
onTouch={setFieldTouched}
onChange={setFieldValue}
/>
</View>
<View style={styles.lineContent}>
<ButtonLoading
loading={isLoading || isSubmitting}
label="Salvar"
style={styles.button}
onPress={handleSubmit}
/>
</View>
</Fragment>
)}
</ScrollView>
</View>
);
}
}
export default withFormik({
mapPropsToValues: (props) => ({
nrCepPre: '',
dsEndereco: '',
nrCep: '',
}),
validationSchema: enderecoSchema,
handleSubmit(values, customObject, bag) {
console.warn('handle');
},
})(Form);
Why not include your handleSubmit() func in your Form class instead by defining it as _hanlderSubmit = (e) = {...} so that there isn't a need for binding it. Then just call it as this._handleSubmit.
You can find more on arrow notation here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
I have some issues with TextInput when getting the data from API when calling the function I'm declaring it to fetch the API and get the data Depending on the input
I have a warning like
can't find variable searchInput
and I'm defining the search input in the state and put them to the value of the input, I think the code is right or what?
Code
import React, { Component } from "react";
import {
StyleSheet,
Text,
View,
TextInput,
LinearGradient,
ActivityIndicator,
TouchableOpacity
} from "react-native";
import Icon from "react-native-vector-icons/Ionicons";
export default class Search extends Component {
constructor() {
super();
this.ApiKey = "****";
this.state = {
searchInput: "",
searchResult: null,
error: "",
isLoading: false
};
}
searchCity = async () => {
this.setState({
isLoading: true
});
const url = `http://api.openweathermap.org/data/2.5/weather?q=${searchInput}&units=metric&appid=${
this.ApiKey
}`;
await fetch(url)
.then(res => res.json())
.then(responseJson =>
this.setState({
isLoading: false,
searchResult: {
name: responseJson.name,
country: responseJson.sys.country,
main: responseJson.weather[0].main,
description: responseJson.weather[0].description,
temp: responseJson.main.temp
}
})
)
.catch(error => this.setState({ error }));
};
render() {
const { searchInput, searchResult, isLoading, error } = this.state;
if (!isLoading) {
return (
<View
style={{
backgroundColor: "#2b3654",
flex: 1,
justifyContent: "center",
alignItems: "center"
}}
>
{isLoading && <Text style={styles.Text}> Loading...</Text>}
<ActivityIndicator size="large" color="00ff00" />
</View>
);
} else if (error) {
return (
<View>
<Text>{error}</Text>
</View>
);
}
if (searchResult) {
return (
<LinearGradient colors={["rgba(0,0,0,0.05)", "rgba(0,0,0,0)"]}>
<View>
<Text>{searchResult.name}</Text>
<Text> {searchResult.main}</Text>
<Text> {searchResult.description}</Text>
<Text> {searchResult.temp}</Text>
</View>
</LinearGradient>
);
} else {
return (
<View style={styles.container}>
<View style={styles.searchSection}>
<TouchableOpacity onPress={this.searchCity}>
<Icon
style={styles.searchIcon}
name="ios-search"
size={15}
color="#fff"
/>
</TouchableOpacity>
<TextInput
style={styles.input}
placeholder="Find Your City.."
placeholderTextColor="#fff"
underlineColorAndroid="transparent"
autoCapitalize="none"
onChangeText={searchInput => {
this.setState({ searchInput });
}}
onSubmitEditing={this.searchCity}
value={searchInput}
/>
</View>
</View>
);
}
}
}
You need to use this.state.searchInput
The line should be:
const url = `http://api.openweathermap.org/data/2.5/weather?q=${this.state.searchInput}...`;
The problem is in your URL, you have used searchInput there...
use this.state.searchInput
or you can use destructuring
const { searchInput } = this.state;
const url = `http://api.openweathermap.org/data/2.5/weather?q=${searchInput}&units=metric&appid=${
this.ApiKey
}`;