how to get the value of Input.Password item in antd - javascript

Now I am design a password change UI in my system, I write the change passowd UI like this:
const ChangePwd = () => (
<Form
{...layout}
name='changepwd'
onFinish={onFinish}
onSubmit={this.handleSubmit}
onFinishFailed={onFinishFailed}>
<Form.Item
label='old password'
name='oldpassword'
rules={[
{
required: true,
message: 'Please input your username!'
}
]}>
<Input />
</Form.Item>
<Form.Item
label='new password'
name='newpassword'
rules={[
{
required: true,
message: 'Please input your password!'
}
]}>
<Input.Password />
</Form.Item>
<Form.Item
label='repeat pasword'
name='newpasswordrepeat'
rules={[
{
required: true,
message: 'Please input your password!'
}
]}>
<Input.Password />
</Form.Item>
<Form.Item {...tailLayout}>
<Button type='primary' htmlType='submit'>
submit
</Button>
</Form.Item>
</Form>
)
I want to get the value of password and send to backend, what should I get the value of the user input? Now I am doing it like this but could not get the value of user input:
handleSubmit = (values) => {
let { oldpassword, newpassword } = values
if (newpassword !== oldpassword) {
alert('new password not equal to old')
return
}
let user = localStorage.getItem("user");
var request = {
phone: user.phone,
oldPassword: oldpassword,
newPassword: newpassword
}
modifyPassword(request)
}

use the onchange event:
<Input.Password value={this.state.oldPassword} onChange={this.handleOldPasswordChange} />
and get the user input like this:
handleOldPasswordChange = e => {
if (this.state.oldPassword !== e.target.value) {
this.setState({
oldPassword: e.target.value
})
}
}
works.

Related

Update React input fields values on demand

I am trying to implement a two-page form in React. On the first page I request a code that I use to fetch some data that I need to display on the second page. Here, by page I mean a different view on the same page. The problem that I am facing is that when I receive a response from the backend API, I use state to update the current state of the fields and this does not seem to happen immediately when I need it. When I change the value of the property that decides which view to render, the fields are still empty, not updating with the values fetched from the API. Now, I know that setState is asynchronous, but I don't know how to handle this situation, since the data fetch is done on demand, not at the beginning, so I don't think I can use useEffect for this job.
Here is my state:
const [state, setState] = useState({
name: "",
cif: "",
address: "",
phone: "",
fax: "",
managerName: "",
email: "",
password: "",
});
const [companyDataFetched, setCompanyDataFetched] = useState(false);
And here are the two views and how I switch between them:
{!companyDataFetched ? (
<CustomForm layout={theme.layout} widthelem={"70%"}>
<Form.Item
name="Company CIF:"
label="Company CIF:"
rules={[
{
pattern: new RegExp(/^\d{2,10}$/),
message: "Invalid CIF!",
},
{
required: true,
message: "Please insert the CIF of the company!",
},
]}
>
<CustomInput
backgroundcolor={theme.white}
onChange={(event) => handleChange(event, "cif")}
/>
</Form.Item>
<CustomButton
backgroundcolor={theme.primaryColor}
textcolor={theme.white}
onClick={() => {
axios.get(`${process.env.REACT_APP_API_URL}/Company/GetByCUI/${state.cif}`)
.then((res) => {
const companyInfo = res.data;
if (companyInfo.name) {
setState((prevState) => {
return {
...prevState,
name: companyInfo.name
};
});
}
if (companyInfo.address) {
setState((prevState) => {
return {
...prevState,
"address": companyInfo.address,
};
});
}
if (companyInfo.phone) {
setState((prevState) => {
return {
...prevState,
"phone": companyInfo.phone,
};
});
}
if (companyInfo.fax) {
setState((prevState) => {
return {
...prevState,
"fax": companyInfo.fax,
};
});
}
setCompanyDataFetched(true);
})
.catch((error) => {
console.log(error);
});
}}
margintop={"13%"}
marginbottom={"13%"}
>
Continue
</CustomButton>
</CustomForm>
) : (
<CustomForm layout={theme.layout} widthelem={"70%"}>
<Form.Item
name="Company name:"
label="Company name:"
rules={[
{
required: true,
message: "Please insert the name of the company!",
whitespace: true,
},
]}
>
<CustomInput
backgroundcolor={theme.white}
onChange={(event) => handleChange(event, "name")}
value={state.name}
/>
</Form.Item>
<Form.Item
name="Company CIF:"
label="Company CIF:"
rules={[
{
pattern: new RegExp(/^\d{2,10}$/),
message: "Invalid CIF!",
},
{
required: true,
message: "Please insert the CIF of the company!",
},
]}
>
<CustomInput
backgroundcolor={theme.white}
onChange={(event) => handleChange(event, "cif")}
value={state.cif}
disabled={true}
/>
</Form.Item>
<Form.Item
name="Address:"
label="Address:"
rules={[
{
required: true,
message: "Please insert the address of the company!",
whitespace: true,
},
]}
>
<CustomInput
backgroundcolor={theme.white}
onChange={(event) => handleChange(event, "address")}
value={state.address}
/>
</Form.Item>
<Form.Item
name="Phone:"
label="Phone:"
rules={[
{
required: true,
message:
"Please insert the phone number of the company!",
whitespace: true,
},
]}
>
<CustomInput
backgroundcolor={theme.white}
onChange={(event) => handleChange(event, "phone")}
value={state.phone}
/>
</Form.Item>
<Form.Item
name="Fax:"
label="Fax:"
rules={[
{
required: true,
message: "Please insert the fax of the company!",
whitespace: true,
},
]}
>
<CustomInput
backgroundcolor={theme.white}
onChange={(event) => handleChange(event, "fax")}
value={state.fax}
/>
</Form.Item>
<Form.Item
name="Manager name:"
label="Manager name:"
rules={[
{
required: true,
message:
"Please, insert the name of the company manager!",
whitespace: true,
},
]}
>
<CustomInput
backgroundcolor={theme.white}
onChange={(event) =>
handleChange(event, "managerName")
}
/>
</Form.Item>
<Form.Item
name="Manager e-mail:"
label="Manager e-mail:"
rules={[
{
type: "email",
message: "Invalid e-mail!",
},
{
required: true,
message:
"Please insert the e-mail of the company manager!",
},
]}
>
<CustomInput
backgroundcolor={theme.white}
onChange={(event) => handleChange(event, "email")}
/>
</Form.Item>
<Form.Item
name="Password:"
label="Password:"
rules={[
{
required: true,
message: "Please, insert a password!",
},
{
min: 4,
message: "Password needs to be at least 4 characters long",
},
]}
>
<CustomInput
backgroundcolor={theme.white}
onChange={(event) => handleChange(event, "password")}
type={"password"}
onKeyPress={verifyCredentials}
/>
</Form.Item>
<CustomButton
backgroundcolor={theme.primaryColor}
textcolor={theme.white}
onClick={() => {
signup();
}}
margintop={"13%"}
marginbottom={"13%"}
>
Register
</CustomButton>
</CustomForm>
)}
The major problem is that when companyDataFetched becomes true, the state containing the field values is not updated and the values of the fields don't update with the data fetched from the backend. How can I handle this issue?
[UPDATE AFTER PAIMAN'S SUGGESTION]
I tried using useEffect and another state for the API response, but the result is the same.
Here is my updated code:
useEffect(() => {
if (companyDataFetched) {
console.log(response);
setState((prevState) => {
return {
...prevState,
nume: response.name,
adresa: response.address,
telefon: response.phone,
fax: response.fax
}
});
}
}, [companyDataFetched, response]);
axios.get(`${process.env.REACT_APP_INTERNSHIP_API_URL}/Company/GetByCUI/${state.cif}`)
.then((res) => {
setResponse(res.data);
setCompanyDataFetched(true);
})
.catch((error) => {
console.log(error);
});
[UPDATE AFTER SANGEET'S SUGGESTION]
I tried using what you suggested. It did not work straight-forward, so I made some changes, but it doesn't work yet.
Here is my updated code:
useEffect(() => {
const fetchData = () => {
return axios
.get(`${process.env.REACT_APP_INTERNSHIP_API_URL}/Company/GetByCUI/${state.cif}`)
.then((res) => {
return res;
})
.catch((error) => {
console.log(error);
});
};
let isMounted = true;
if (companyDataFetched) {
(async () => {
const response = await fetchData();
if (isMounted) {
setState((prevState) => {
return {
...prevState,
name: response.data.name,
address: response.data.address,
phone: response.data.phone,
fax: response.data.fax,
};
});
} else {
setCompanyDataFetched(false);
}
})();
}
return function () {
isMounted = false;
};
}, [companyDataFetched, state.cif]);
Don't have your API call in the onClick handler. Instead trigger the fetch in the button by saying setCompanyDataFetch(true).
Then have a useEffect with companyDataFetch as a dependency.
function fetchData() {
return axios.get(`${process.env.REACT_APP_INTERNSHIP_API_URL}/Company/GetByCUI/${state.cif}`)
.then((res) => {
// setResponse(res.data);
// setCompanyDataFetched(true);
return res;
})
.catch((error) => {
console.log(error);
});
}
Your useEffect looks like so
useEffect(() => {
let isMounted = true;
if (companyDataFetched) {
(async () => {
const response = await fetchData()
if (isMounted) setState((prevState) => {
return {
...prevState,
nume: response.name,
adresa: response.address,
telefon: response.phone,
fax: response.fax
}
});
if (isMounted) setCompanyDataFetched(false);
})();
}
return function () {
isMounted = false;
};
}, [companyDataFetched]);
[UPDATED!] multi-step form implementation. pretend you get the phone number in step 1 then email in step 2.
// component.js
export default function MultiForm(){
const [step , setStep] = useState(1);
const [inputs , setInputs] = useState({
phone : '',
email : ''
});
const handleStep1 = () => {
// validation
if(inputs.phone !== ""){
// set step 2
setStep(2)
}
}
}
const handleStep2 = async() => {
// validation
if(inputs.email !== ""){
const { data , status } = await axios.post(url ,{
phone : inputs.phone,
email : inputs.email
})
if(status === 200){
alert('Registered successfully')
}
}
}
}
return (
<>
{step === 1 && (
<>
<input name="phone" onChange={(e) =>{
setInputs({...inputs , [e.target.name] : e.target.value})
}} />
<button onClick={handleStep1}>Continue</button>
</>
)}
{step === 2 && (
<input name="email" onChange={(e) =>{
setInputs({...inputs , [e.target.name] : e.target.value})
}} />
<button onClick={handleStep2}>Submit</button>
)}
</>
)
}
After a lot of research, I discovered that I was setting the input fields values in a wrong way. Apparently, when using antd Form, it must be initialized and used its reference to dynamically change Form.Item values, like so:
const [form] = Form.useForm();
const [step, setStep] = useState(1);
const [state, setState] = useState({
name: "",
cif: "",
address: "",
phone: "",
fax: "",
contactName: "",
email: "",
password: "",
});
const fetchCompanyData = async () => {
const response = await axios.get(`${process.env.REACT_APP_INTERNSHIP_API_URL}/Company/GetByCUI/${state.cif}`);
setState((prevState) => {
return {
...prevState,
nume: response.data.denumire,
adresa: response.data.adresa,
telefon: response.data.telefon,
fax: response.data.fax,
};
});
form.setFieldsValue({
nume: response.data.denumire,
cif: state.cif,
adresa: response.data.adresa,
telefon: response.data.telefon,
fax: response.data.fax,
});
setStep(2);
};
};
[...]
{step === 1 && (
<CustomForm form={form} layout={theme.layout} widthelem={"70%"}>
<Form.Item
name="Company name:"
label="Company name:"
rules={[
{
pattern: new RegExp(/^\d{2,10}$/),
message: "Invalid CIF!",
},
{
required: true,
message: "Please insert the company CIF!",
},
]}
>
<CustomInput
backgroundcolor={theme.white}
onChange={(event) => handleChange(event, "cif")}
/>
</Form.Item>
<CustomButton
backgroundcolor={theme.primaryColor}
textcolor={theme.white}
onClick={fetchCompanyData}
margintop={"13%"}
marginbottom={"13%"}
>
Continue
</CustomButton>
<CustomForm>
)}
{step === 2 && (
<CustomForm form={form} layout={theme.layout} widthelem={"70%"}>
<Form.Item
name="Company name:"
label="Company name:"
rules={[
{
required: true,
message: "Please insert the name of the company!",
whitespace: true,
},
]}
>
<CustomInput
backgroundcolor={theme.white}
onChange={(event) => handleChange(event, "name")}
/>
</Form.Item>
[...]
<CustomForm>
)}

implement loading screen react

So i have this react / node app where basically when I hit register after entering in all my details, it takes me to the stripe checkout page. However, i've been reading firebase goes into a cold start, after 2-3 minutes of no invocations. This is a problem, because we don't expect to get large traffic into our app for another 6 months, which means that there isn't going to be a person using the app every 2-3 minutes.
Right now, during that limbo period between registration and stripe checkout, it goes into a white screen, for like 8 seconds. How can I get this to be a loading screen instead, like one of those react spinning loaders as a temp fix so our customers don't get worried the app is breaking on them?
here's my code for the registration page and then the function that calls stripe:
let firestore = firebase.firestore()
const FormItem = Form.Item
var userIDStripeSubmit = ""
class RegistrationForm extends React.Component {
state = {
confirmDirty: false,
}
onSubmit = (event) => {
event.preventDefault();
this.props.form.validateFields((err, values) => {
if (err) return
const email = this.props.form.getFieldValue('email')
const passwordOne = this.props.form.getFieldValue('password1')
const firstName = this.props.form.getFieldValue('First Name')
const lastName = this.props.form.getFieldValue('Last Name')
const companyName = this.props.form.getFieldValue('Company Name')
const {
history,
} = this.props
AuthorizationHome.doCreateUserWithEmailAndPassword(email, passwordOne)
.then((authUser) => facades.userFacade().doCreateUser(authUser.user.uid, email))
.catch(error => {
this.setState({'error': error})
})
// adding into profiledata collection
// var userID = ""
firebase.auth().onAuthStateChanged((user) => {
if(user) {
console.log(user.uid)
userIDStripeSubmit = user.uid
console.log("userid inside firebase auth is" + user.uid)
// var firstNameFromField =
firestore.collection('profiledata').doc(user.uid).set({
firstname: firstName,
lastname: lastName,
companyname: companyName,
accountStatus: "inactive",
})
.catch(error => {
alert(error.message);
});
createCheckoutSession(user.uid)
}
})
// firestore collection query
})
}
handleConfirmBlur = (e) => {
const value = e.target.value;
this.setState({ confirmDirty: this.state.confirmDirty || !!value });
}
compareToFirstPassword = (rule, value, callback) => {
const form = this.props.form;
if (value && value !== form.getFieldValue('password1')) {
callback('Passwords do not match!');
} else {
callback();
}
}
validateToNextPassword = (rule, value, callback) => {
const form = this.props.form;
if (value && this.state.confirmDirty) {
form.validateFields(['password2'], { force: true });
}
callback();
}
render() {
const { getFieldDecorator } = this.props.form
const { error } = this.state
return (
<Form onSubmit={this.onSubmit} hideRequiredMark={true} className="registration-form" style={{ marginBottom: "0px" }}>
{ error && <Alert type="error" message={error.message}/> }
<FormItem label="Email" colon={false} style={{ marginBottom: "0px" }}>
{getFieldDecorator('email', {
rules: [{
type: 'email', message: 'Invalid email address',
}, {
required: true, message: 'Please input your email address',
}],
})(
<Input placeholder="Enter email" />
)}
</FormItem>
{/* */}
<FormItem label="First Name" colon={false} style={{ marginBottom: "0px" }}>
{getFieldDecorator('First Name', {
rules: [{
required: true, message: 'Please enter your First Name',
}],
})(
<Input type="text" placeholder="Enter Your First Name"/>
)}
</FormItem>
<FormItem label="Last Name" colon={false} style={{ marginBottom: "0px" }}>
{getFieldDecorator('Last Name', {
rules: [{
required: true, message: 'Please enter your Last Name',
}],
})(
<Input type="text" placeholder="Enter Your Last Name"/>
)}
</FormItem>
<FormItem label="Company Name" colon={false} style={{ marginBottom: "0px" }}>
{getFieldDecorator('Company Name', {
rules: [{
required: true, message: 'Please enter your Company Name',
}],
})(
<Input type="text" placeholder="Enter Your Company Name"/>
)}
</FormItem>
<FormItem label="Password" colon={false} style={{ marginBottom: "0px" }}>
{getFieldDecorator('password1', {
rules: [{
required: true, message: 'Please choose a password',
}, {
validator: this.validateToNextPassword,
}],
})(
<Input type="password" placeholder="Enter password"/>
)}
</FormItem>
<FormItem label="Confirm Password" colon={false} style={{ marginBottom: "0px" }}>
{getFieldDecorator('password2', {
rules: [{
required: true, message: 'Please confirm your password',
}, {
validator: this.compareToFirstPassword,
}],
})(
<Input type="password" onBlur={this.handleConfirmBlur} placeholder="Confirm password" />
)}
</FormItem>
<FormItem>
<Button type="primary" htmlType="submit" id="submitButton">Register</Button>
</FormItem>
</Form>
);
}
}
const WrappedRegistrationForm = Form.create()(RegistrationForm);
export default withRouter(WrappedRegistrationForm)
i am new to react, so please let me know if there's anything I can do to make the code easier to read or anything. I'm not sure how to create or where to put the loading spinner
You will need to implement a loading default that is displayed in your base HTML file, this is found inside your public directory as index.html.
Please refer to this answer: https://stackoverflow.com/a/60404990/2301161

page not displaying elements react

this may not be able to be answered, but I am going to try to include as much detail as possible. I have this page called registrationForm.js, which in my routes.js is set to render with the path /signup. It does render the page, but it is blank. When I refresh the page, for a split second I see all the elements I'm supposed to, the input fields, the buttons, the images. But for some reason, it goes back to being fully white page.
Here is the entire registrationForm.js code!
import React from 'react'
import './RegistrationForm.css'
import { Alert, Button, Form, Input } from 'antd'
import { AuthorizationHome } from '../models'
import { withRouter } from 'react-router-dom'
import * as routes from '../routes'
import facades from '../facades'
import firebase from 'firebase'
import { useState } from "react";
import {createCheckoutSession} from '../Stripepayment/checkout'
let firestore = firebase.firestore()
const FormItem = Form.Item
// const [firstname, setFirstName] = useState("");
// const [lastname, setLastName] = useState("");
// const [companyname, setCompanyName] = useState("");
// const [accountStatus, setAccountStatus] = useState("");
var userIDStripeSubmit = ""
class RegistrationForm extends React.Component {
state = {
confirmDirty: false,
}
onSubmit = (event) => {
event.preventDefault();
this.props.form.validateFields((err, values) => {
if (err) return
const email = this.props.form.getFieldValue('email')
const passwordOne = this.props.form.getFieldValue('password1')
const firstName = this.props.form.getFieldValue('First Name')
const lastName = this.props.form.getFieldValue('Last Name')
const companyName = this.props.form.getFieldValue('Company Name')
const {
history,
} = this.props
AuthorizationHome.doCreateUserWithEmailAndPassword(email, passwordOne)
.then((authUser) => facades.userFacade().doCreateUser(authUser.user.uid, email))
// .then((authUser) => {
// history.push(createCheckoutSession(authUser.user.uid))
// })
.catch(error => {
this.setState({'error': error})
})
// adding into profiledata collection
// var userID = ""
firebase.auth().onAuthStateChanged((user) => {
if(user) {
// console.log("profile.js " + user.uid)
// userID = user.uid
// userID = user.uid
console.log(user.uid)
userIDStripeSubmit = user.uid
console.log("userid inside firebase auth is" + user.uid)
// var firstNameFromField =
// console.log("this props : " + this.props.form.getFieldValue('First Name'))
firestore.collection('profiledata').doc(user.uid).set({
firstname: firstName,
lastname: lastName,
companyname: companyName,
accountStatus: "inactive",
})
.catch(error => {
alert(error.message);
});
createCheckoutSession(user.uid)
}
})
// firestore collection query
// setFirstName("");
// setLastName("");
// setCompanyName("");
// setAccountStatus("")
})
}
handleConfirmBlur = (e) => {
const value = e.target.value;
this.setState({ confirmDirty: this.state.confirmDirty || !!value });
}
compareToFirstPassword = (rule, value, callback) => {
const form = this.props.form;
if (value && value !== form.getFieldValue('password1')) {
callback('Passwords do not match!');
} else {
callback();
}
}
validateToNextPassword = (rule, value, callback) => {
const form = this.props.form;
if (value && this.state.confirmDirty) {
form.validateFields(['password2'], { force: true });
}
callback();
}
render() {
const { getFieldDecorator } = this.props.form
const { error } = this.state
return (
<Form onSubmit={this.onSubmit} hideRequiredMark={true} className="registration-form" style={{ marginBottom: "0px" }}>
{ error && <Alert type="error" message={error.message}/> }
<FormItem label="Email" colon={false} style={{ marginBottom: "0px" }}>
{getFieldDecorator('email', {
rules: [{
type: 'email', message: 'Invalid email address',
}, {
required: true, message: 'Please input your email address',
}],
})(
<Input placeholder="Enter email" />
)}
</FormItem>
{/* */}
<FormItem label="First Name" colon={false} style={{ marginBottom: "0px" }}>
{getFieldDecorator('First Name', {
rules: [{
required: true, message: 'Please enter your First Name',
}],
})(
<Input type="text" placeholder="Enter Your First Name"/>
)}
</FormItem>
<FormItem label="Last Name" colon={false} style={{ marginBottom: "0px" }}>
{getFieldDecorator('Last Name', {
rules: [{
required: true, message: 'Please enter your Last Name',
}],
})(
<Input type="text" placeholder="Enter Your Last Name"/>
)}
</FormItem>
<FormItem label="Company Name" colon={false} style={{ marginBottom: "0px" }}>
{getFieldDecorator('Company Name', {
rules: [{
required: true, message: 'Please enter your Company Name',
}],
})(
<Input type="text" placeholder="Enter Your Company Name"/>
)}
</FormItem>
<FormItem label="Password" colon={false} style={{ marginBottom: "0px" }}>
{getFieldDecorator('password1', {
rules: [{
required: true, message: 'Please choose a password',
}, {
validator: this.validateToNextPassword,
}],
})(
<Input type="password" placeholder="Enter password"/>
)}
</FormItem>
<FormItem label="Confirm Password" colon={false} style={{ marginBottom: "0px" }}>
{getFieldDecorator('password2', {
rules: [{
required: true, message: 'Please confirm your password',
}, {
validator: this.compareToFirstPassword,
}],
})(
<Input type="password" onBlur={this.handleConfirmBlur} placeholder="Confirm password" />
)}
</FormItem>
{/* inserting into profiledata collection firestore */}
{/* ending profiledata collection insert firestore */}
{/*
<FormItem label="First Name" colon={false} >
<Input placeholder = "Enter Your First Name" style={{ maxWidth: '100%', maxHeight: '50%' , }}
value = { firstname }
onChange = {
(e) => setFirstName(e.target.value)
}/>
</FormItem>
<FormItem label="Last Name" colon={false}>
<Input placeholder = "Enter Your Last Name" style={{ maxWidth: '100%', maxHeight: '50%' }}
value = { lastname }
onChange = {
(e) => setLastName(e.target.value)
}/>
</FormItem>
<FormItem label="Company Name" colon={false}> <
Input placeholder = "Enter Your Company name." style={{ maxWidth: '100%', maxHeight: '50%' }}
value = { companyname }
onChange = {
(e) => setCompanyName(e.target.value)
}
/ >
</FormItem> */}
<FormItem>
<Button type="primary" htmlType="submit" id="submitButton">Register</Button>
</FormItem>
</Form>
);
}
}
const WrappedRegistrationForm = Form.create()(RegistrationForm);
export default withRouter(WrappedRegistrationForm)
am I missing something to actually render the elements on page?! All my other pages are rendering fine, just not this one! Any suggestions?

How to bind multiple onChange callback for different inputs?

I am making a different form component using ant design and trying to bind several different inputs
Here is the code :
this.state = {
title: '',
product: '',
options: 0,
price: 0,
}
onTitleChange = (e) => {
this.setState({
title: e.target.value
})
}
onProductChange = (e) => {
this.setState({
product: e.target.value
})
}
onHandleChange = value => {
this.setState({
priceOption: value
})
}
onNumberChange = e => {
this.setState({
price: e.target.value
})
}
<FormItemRow>
<Col span={24} style={colStyle}>
<FormItem label={'title'} colon={false} style={{ marginBottom: 0 }}>
{getFieldDecorator('title', {
rules: [
{ required: true, message: 'title is required' },
],
})(<Input onChange={this.onTitleChange}/>)}
</FormItem>
</Col>
</FormItemRow>
<FormItemRow>
<Col span={24} style={colStyle}>
<FormItem label={'product-number'} colon={false} style={{ marginBottom: 0 }}>
{getFieldDecorator('product-number', {
rules: [{ required: true, message: 'product-number is required' }],
})(<Input onChange={this.onProductChange}/>)}
</FormItem>
</Col>
</FormItemRow>
<FormItemRow>
<Col span={12} style={colStyle}>
<FormItem label={'options'} colon={false} style={{ marginBottom: 0 }}>
{getFieldDecorator('options', {
rules: [
{ required: true, message: 'options is required' },
],
})(<Select onChange={this.onHandleChange}>{this.handWashOptions(this.props.handWashOptions)}</Select>)}
</FormItem>
</Col>
<Col span={12} style={colStyle}>
<FormItem label={'price'} colon={false} style={{ marginBottom: 0 }}>
{getFieldDecorator('price', {
rules: [
{ required: true, message: 'price is required' },
],
})(<Input type="number" onChange={this.onNumberChange}/>)}
</FormItem>
</Col>
</FormItemRow>
title and product using just Input component.
option is using Select component.
and price is using Input type number component.
I think it is very inefficient using different onChange callback on each input component.
Is there any way I can bind one onChange callback function?
You can simply make a generic function handleChange, pass the name and value which are to be updated
handleChange(name,value){
this.setState({[name]: value})
}
and pass value to handle change like this
<Input onChange={(name,value)=>this.onTitleChange(name,value)}/>
You can use e.target.value to get value from target, also if you need to have different logic for some particular element then you can simply add a exception in handleChange
this.state = {
fields:{
each:
field:
you:
have:
}
}
handleChange = (event) => {
const { value, type, name } = event.currentTarget
console.log(type, value, name);
this.setState(prevState => ({
fields: {
...prevState.fields,
[name]: type === 'number' ? parseInt(value, 10) : value
}
}));
};
As stated in Handling Multiple Inputs,
add a name attribute to each element and let the handler function choose what to do based on the value of event.target.name.
So you can have:
onChange = event => {
const name = event.target.name;
this.setState({
[name]: event.target.value
})
}
// Add `name` attribute used for event.target.name
<Select onChange={this.onChange} name="wash">...</Select>
<Input type="number" onChange={this.onChange} name="number"/>
<Input onChange={this.onChange} name="product" />

how to handle backend errors in js frontend inside of object and with out object

i have user login and i have 2 errors handlers
email & password empty
email & password not match with data base
through post man i send
empty user name and password result is
{
"errors": {
"email": "please enter valid emails",
"password": "please enter password"
}
}
email and password wrong the result is
{
"general": "email or password not match"
}
i notice 1st error its have object errors and 2nd not have
my react js code is
// i remove css and imports
class login extends Component {
constructor() {
super();
this.state = {
email: '',
password: '',
loading: false,
errors: {}
}
}
handleChnage = (event) => {
this.setState({
[event.target.name]: event.target.value
})
}
handleSubmit = (event) => {
// console.log('hi');
event.preventDefault();
this.setState({
loading: true
});
const userData = {
email: this.state.email,
password: this.state.password
}
axios.post('/login', userData)
.then((res) => {
//console.log(res.data)
this.setState({
loading: false
});
this.props.history.push('/');
})
.catch((err) => {
console.log(err.response.data)
// let errors ={email:'',password:''}
this.setState({
//errors11: err.response.data.errors,
errors : err.response.data.errors,
// error2:err.response.data,
loading: false
})
})
}
render() {
const { classes } = this.props;
const { errors, loading,} = this.state;
return (
<Grid container className={classes.form}>
<Grid item sm />
<Grid item sm >
<img src={AppIcon} alt="app cion" className={classes.image} />
<Typography variant="h2" className={classes.pagetitle}>Login</Typography>
<form noValidate onSubmit={this.handleSubmit}>
<TextField id="email" name="email" type="email" label="Email" className={classes.textfeild}
helperText={errors.email} error={errors.email ? true : false} value={this.state.email} onChange={this.handleChnage} fullWidth />
<TextField id="password" name="password" type="password" label="Password" className={classes.textfeild}
helperText={errors.password} error={errors.password ? true : false} value={this.state.password} onChange={this.handleChnage} fullWidth />
{errors.general &&(
<Typography variant="body2" className={classes.customerror}>
{errors.general}
</Typography>
)}
<Button type="submit" variant="contained" color="primary" className={classes.button}>Login </Button>
</form>
</Grid>
<Grid item sm />
</Grid>
)
}
}
login.propTypes = {
classes: PropTypes.object.isRequired
}
export default withStyles(styles)(login);
my problem is in this code if i send email and password wrong
93 | helperText={errors.email} error={errors.email ? true : false} value={this.state.email} onChange={this.handleChnage} fullWidth
this line i got error and this is my console log
general: "email or password not match"
how can i handle this kind of errors ?
Looking at the code of your request handling and the responses I can see that error responses are not consistent in how it handles errors. I think you should think about fixing the response to be consistent. I would try to replace line in error handling of submit
errors : err.response.data.errors,
with something that would create structure for general erros: f.e.
errors : {...err.response.data.errors, general: err.response.data.general}

Categories

Resources