reactjs fetch with parameters from cognito - javascript

I'm trying to get the currently logged in users email and use it in my fetch() call. I can currently get the email from getfirstapi() and use it in my form but I'm having trouble passing it into my getSecondApi() where the fetch() is ?
Iv tried creating a getEmail function to return it, but with no luck.
Code
import * as React from "react";
import axios from "axios";
import { Form, Card, Grid } from "tabler-react";
import { Button, Modal } from "semantic-ui-react";
import Auth from '#aws-amplify/auth';
import '../../index.css';
import { arrayOf } from "prop-types";
//const config = require('../config.json');
class GeneralInformation extends React.Component {
constructor(props) {
super(props);
this.state = {
// States from API
firstname: "",
middlename: "",
surname: "",
city: "",
postcode: "",
state: "",
email: "",
about: "",
// States for editable form
formfirstname: "",
formmiddlename: "",
formsurname: "",
formcity: "",
formpostcode: "",
formstate: "",
formabout: "",
// Modal State
open: false,
};
}
getUseremail() {
return Auth.currentAuthenticatedUser().then(user => user.attributes.email)
}
email = Auth.currentAuthenticatedUser().then(user => user.attributes.email)
getFirstApi() {
return Auth.currentAuthenticatedUser().then((user) => {
this.setState({email: user.attributes.email, formemail: user.attributes.email})
});
}
getSecondApi(email) {
fetch(`https://ezha2ns0bl.execute-api.ap-southeast-2.amazonaws.com/prod/userdata?foo=${encodeURIComponent(email)}`)
.then(res => res.json())
.then(
console.log("THIS IS RESULT2 " + email),
(result) => {
this.setState({
firstname: result.Item.userFirstName,
middlename: result.Item.userMiddleName,
surname: result.Item.userLastName,
city: result.Item.userCity,
postcode: result.Item.userPostcode,
state: result.Item.userState,
about: result.Item.userAbout,
formfirstname: result.Item.userFirstName,
formmiddlename: result.Item.userMiddleName,
formsurname: result.Item.userLastName,
formcity: result.Item.userCity,
formpostcode: result.postcode,
formstate: result.Item.userState,
formabout: result.Item.userAbout,
});
console.log("THIS IS RESULT1 " + result)} ,
)
}
componentDidMount() {
this.getFirstApi();
this.getSecondApi();
}
handleChange = (input) => (event) => {
this.setState({ [input]: event.target.value });
};
handleSubmit = async (event) => {
event.preventDefault();
this.setState((prevState) => ({
// If submitting new values, update the state to represent the new data
firstname: prevState.formfirstname,
middlename: prevState.formmiddlename,
surname: prevState.formsurname,
city: prevState.formcity,
postcode: prevState.formpostcode,
email: prevState.formemail,
userState: prevState.formstate,
about: prevState.formabout,
open: false,
}))
try {
const params = {
"userFirstName": this.state.formfirstname,
"userMiddleName": this.state.formmiddlename,
"userLastName": this.state.formsurname,
"userCity": this.state.formcity,
"userPostCode": this.state.formpostcode,
"userEmail": this.state.formemail,
"userState": this.state.formstate,
"userAbout": this.state.formabout,
"userType": "jobseeker"
};
await axios.post('https://qrg3idkox4.execute-api.ap-southeast-2.amazonaws.com/prod/{userEmail}/', params);
}catch (err) {
console.log(`An error has occurred: ${err}`);
}
};
cancelForm = () => {
// If cancelling, reset any fields that have been changed to the original values so that when the modal is re-opened, the old values are shown
this.setState((prevState) => ({
formfirstname: prevState.firstname,
formmiddlename: prevState.middlename,
formsurname: prevState.surname,
formcity: prevState.city,
formpostcode: prevState.postcode,
formstate: prevState.state,
formabout: prevState.about,
open: false,
}));
};
openModal = () => {
this.setState({ open: true });
};
render() {
const {
firstname,
middlename,
surname,
city,
postcode,
state,
email,
about,
formfirstname,
formmiddlename,
formsurname,
formcity,
formpostcode,
formstate,
formabout,
open,
} = this.state;
return (
<div className="card" name="generalInfo">
<Card.Body>
<Grid>
<Grid.Row>
<Grid.Col md={7}>
<Card.Title>General Information</Card.Title>
</Grid.Col>
<Grid.Col md={5}>
{/* MODAL BUTTON */}
<Button
floated="right"
basic
icon="pencil"
type="button"
compact
onClick={this.openModal}
/>
</Grid.Col>
</Grid.Row>
<Grid.Row>
{/* ROW 1 */}
<Grid.Col md={4}>
<Form.Group label="First Name">
<Form.Input name="firstname" readOnly value={firstname} />
</Form.Group>
</Grid.Col>
<Grid.Col md={4}>
<Form.Group label="Middle Name">
<Form.Input name="middlename" readOnly value={middlename} />
</Form.Group>
</Grid.Col>
<Grid.Col md={4}>
<Form.Group label="Surname">
<Form.Input name="surname" readOnly value={surname} />
</Form.Group>
</Grid.Col>
{/* ROW 2 */}
<Grid.Col md={3}>
<Form.Group label="City">
<Form.Input name="city" readOnly value={city} />
</Form.Group>
</Grid.Col>
<Grid.Col md={2}>
<Form.Group label="Post Code">
<Form.Input name="postcode" readOnly value={postcode} />
</Form.Group>
</Grid.Col>
<Grid.Col md={3}>
<Form.Group label="State">
<Form.Input name="state" readOnly value={state} />
</Form.Group>
</Grid.Col>
<Grid.Col md={4}>
<Form.Group label="Email">
<Form.Input name="email" readOnly value={email} />
</Form.Group>
</Grid.Col>
{/* ROW 3 */}
<Grid.Col md={12}>
<Form.Group className="mb=0" label="About Me">
<Form.Textarea
name="aboutme"
rows={3}
disabled
readOnly
value={about}
/>
</Form.Group>
</Grid.Col>
</Grid.Row>
</Grid>
</Card.Body>
{/* MODAL CONTENT */}
<Modal
style={{ position: "relative" }}
closeOnDimmerClick={false}
open={open}
>
<Modal.Header>Edit Info</Modal.Header>
<Modal.Content>
<Form onSubmit={this.handleSubmit}>
<Grid.Row>
<Grid.Col md={4}>
<Form.Group label="First Name">
<Form.Input
name="firstname"
value={formfirstname}
onChange={this.handleChange("formfirstname")}
/>
</Form.Group>
</Grid.Col>
<Grid.Col md={4}>
<Form.Group label="Middle Name">
<Form.Input
name="middlename"
value={formmiddlename}
onChange={this.handleChange("formmiddlename")}
/>
</Form.Group>
</Grid.Col>
<Grid.Col md={4}>
<Form.Group label="Surname">
<Form.Input
name="surname"
value={formsurname}
onChange={this.handleChange("formsurname")}
/>
</Form.Group>
</Grid.Col>
</Grid.Row>
{/* ROW 2 */}
<Grid.Row>
<Grid.Col md={3}>
<Form.Group label="City">
<Form.Input
name="city"
value={formcity}
onChange={this.handleChange("formcity")}
/>
</Form.Group>
</Grid.Col>
<Grid.Col md={2}>
<Form.Group label="Post Code">
<Form.Input
name="postcode"
value={formpostcode}
onChange={this.handleChange("formpostcode")}
/>
</Form.Group>
</Grid.Col>
<Grid.Col md={3}>
<Form.Group label="State">
<Form.Input
name="state"
value={formstate}
onChange={this.handleChange("formstate")}
/>
</Form.Group>
</Grid.Col>
</Grid.Row>
{/* ROW 3 */}
<Grid.Row>
<Grid.Col md={12}>
<Form.Group className="mb=0" label="About Me">
<Form.Textarea
name="aboutme"
rows={3}
value={formabout}
onChange={this.handleChange("formabout")}
/>
</Form.Group>
</Grid.Col>
</Grid.Row>
{/* ROW 4 - SUBMIT */}
<Grid.Row>
<Grid.Col md={12}>
<Button
floated="left"
basic
type="button"
color="red"
onClick={this.cancelForm}
>
{" "}
Cancel{" "}
</Button>
<Button floated="right" basic type="submit" color="green">
{" "}
Accept Changes{" "}
</Button>
</Grid.Col>
</Grid.Row>
</Form>
</Modal.Content>
</Modal>
</div>
);
}
}
export default GeneralInformation;
Form
EDIT
> getEmailApi() { return
> Auth.currentAuthenticatedUser().then((user) => {
> const { attributes = {} } = user;
> console.log(attributes['email']);
> })}
iv created this function to get the email
but don't know how to pass it into the getSecondApi

My Solution
getEmailApi() {
return Auth.currentAuthenticatedUser().then((user) => {
const { attributes = {} } = user;
console.log(attributes['email']);
let email = attributes['email']
return email
})}
getFirstApi() {
return Auth.currentAuthenticatedUser().then((user) => {
this.setState({email: user.attributes.email, formemail: user.attributes.email})
});
}
getSecondApi(email) {
fetch(`https://ezha2ns0bl.execute-api.ap-southeast-2.amazonaws.com/prod/userdata?userEmail=${encodeURIComponent(email)}`)
.then(res => res.json())
.then(
console.log("THIS IS RESULT2 " + email),
(result) => {
this.setState({
firstname: result.Item.userFirstName,
middlename: result.Item.userMiddleName,
surname: result.Item.userLastName,
city: result.Item.userCity,
postcode: result.Item.userPostcode,
state: result.Item.userState,
about: result.Item.userAbout,
formfirstname: result.Item.userFirstName,
formmiddlename: result.Item.userMiddleName,
formsurname: result.Item.userLastName,
formcity: result.Item.userCity,
formpostcode: result.postcode,
formstate: result.Item.userState,
formabout: result.Item.userAbout,
});
console.log("THIS IS RESULT1 " + result)} ,
)
}
BeforDidMount() {
this.getEmailApi().then(email => this.getSecondApi(email)); }
componentDidMount() {
this.BeforDidMount();
this.getFirstApi();
}

Related

React JS Show Proper Modals

I have a registration form where if successful a success modal message pops up and if a error specifically same username or email is used an error modal message pops up. Yet for some reason if registration process is fine (no duplicate username or email) the error message still appears. See code below:
export default function Register() {
const [show, setShow] = useState(null)
const [ error, setError] = useState(null)
const [showError, setShowError] = useState(null)
const handleClose = function () {
setShow(false)
}
const handleSubmit = function () {
setShowError(false)
}
const dataSet = useFormik({
initialValues: {
name: '',
surname: '',
username: '',
email: '',
passcode: '',
confirm: ''
},
})
const validate = Yup.object().shape({
name: Yup.string().required('Name is required'),
surname: Yup.string().required('Surname is required'),
username: Yup.string().required('A Username is required')
.min(5, 'Username must be at least 5 characters')
.max(20, 'Username must not exceed more than 20 characters'),
email: Yup.string().required('Email is required')
.email('Email is Invalid'),
passcode: Yup.string().required('Passcode is required')
.min(5, 'Passcode at least 5 characters')
.max(10, 'Passcode must not exceed 20 characters'),
confirm: Yup.string().required('Confirmation Passcode is required')
.oneOf([Yup.ref('passcode'), null], 'Confirm Passcode does not match')
})
return (
<div className='register-form'>
<Formik initialValues={{dataSet}} validationSchema={validate} validateOnChange={true}
onSubmit={ async (values, actions) => {
try {
await axios.post('/auth/register', values)
setShow(true)
setShowError(false)
actions.setSubmitting(false)
actions.resetForm({
values:{
name: '',
surname: '',
username: '',
email: '',
passcode: '',
confirm: ''
}
})
} catch (error) {
setError(error.response.data)
if(error) {
setShowError(true)
setShow(false)
}
}
}}>
{({handleSubmit, handleChange, values, touched, isValid, errors }) => (
<Form noValidate onSubmit={handleSubmit} >
<h1>Admin Panel Register</h1>
<Row>
<Form.Group as={Col} controlId='formGridName' className='position-relative'>
<Form.Label>Name</Form.Label>
<Form.Control type={'text'}
name={'name'}
placeholder={'Type Name'}
value={values.name}
onChange={handleChange}
isValid={touched.name}
isInvalid={!!errors.name} />
<Form.Control.Feedback type='invalid' tooltip>{errors.name}</Form.Control.Feedback>
</Form.Group>
<Form.Group as={Col} controlId='formGridSurname' className='position-relative'>
<Form.Label>Surname</Form.Label>
<Form.Control type={'text'}
name={'surname'}
placeholder={'Type Surname'}
value={values.surname}
onChange={handleChange}
isValid={touched.surname}
isInvalid={!!errors.surname} />
<Form.Control.Feedback type='invalid' tooltip>{errors.surname}</Form.Control.Feedback>
</Form.Group>
</Row>
<Row>
<Form.Group as={Col} md='6' controlId='formGridEmail' className='position-relative'>
<Form.Label>Email</Form.Label>
<Form.Control type={'email'}
name={'email'}
placeholder={'Type Email'}
value={values.email}
onChange={handleChange}
isInvalid={!!errors.email}/>
<Form.Control.Feedback type='invalid' tooltip>{errors.email}</Form.Control.Feedback>
</Form.Group>
<Form.Group controlId='formGridUsername' className='position-relative mb-3'>
<Form.Label>Username</Form.Label>
<Form.Control type={'text'}
name={'username'}
placeholder={'Enter Userame'}
value={values.username}
onChange={handleChange}
isInvalid={!!errors.username} />
<Form.Control.Feedback type='invalid' tooltip>{errors.username}</Form.Control.Feedback>
</Form.Group>
<Form.Group controlId='formGridPasscode' className='position-relative mb-3'>
<Form.Label>Passcode</Form.Label>
<Form.Control type={'password'}
name={'passcode'}
placeholder={'Enter Passcode'}
value={values.passcode}
onChange={handleChange}
isInvalid={!!errors.passcode} />
<Form.Control.Feedback type='invalid' tooltip>{errors.passcode}</Form.Control.Feedback>
</Form.Group>
<Form.Group as={Col} controlId='formGridConfirm' className='position-relative mb-3'>
<Form.Label>Confirm</Form.Label>
<Form.Control type={'password'}
name={'confirm'}
placeholder={'Confirm Passcode'}
value={values.confirm}
onChange={handleChange}
isInvalid={!!errors.confirm} />
<Form.Control.Feedback type='invalid' tooltip>{errors.confirm}</Form.Control.Feedback>
</Form.Group>
</Row>
<Form.Group as={Col} controlId='formGridSubmit'>
<Button variant={'primary'} type={'submit'} >Submit</Button>
</Form.Group>
</Form>
)}
</Formik>
{ error ? (<Modal show={showError} onHide={handleSubmit}>
<Modal.Header closeButton>
<Modal.Title><ErrorOutlineOutlined />{" "}Error</Modal.Title>
</Modal.Header>
<Modal.Body>{error && <p>{error}</p>}</Modal.Body>
<Modal.Footer>
</Modal.Footer>
</Modal>):( <Modal show={show} onHide={handleClose}>
<Modal.Header>
<Modal.Title><InfoOutlined />{" "}Info</Modal.Title>
</Modal.Header>
<Modal.Body>Registration Complete</Modal.Body>
<Modal.Footer>
<Button href={'/admin/login'}>Go to Login </Button>
</Modal.Footer>
</Modal>)}
</div>)
}

React can't print the form data in console

So, this is my App.js file and the next picture is what I get when I hit submit. I want to get all the entered values to be printed on console but that's not happening.
I am also using Flask as backend and I want to get all these data into app.py so how to do that ?
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
petalLen: "",
petalWid: "",
sepalLen: "",
sepalWid: "",
};
this.handleOnChange = this.handleOnChange.bind(this);
}
handleOnChange(event) {
this.setState({ [event.target.name]: event.target.value });
}
handleSubmit(event) {
event.preventDefault();
const data = new FormData(event);
for (let [key, value] of data.entries()) {
console.log(key, value);
}
}
render() {
return (
<div className="App">
<h1>Deploy Models for Humans </h1>
<Form>
<Container>
<Row className="Rr">
<Col>
<Form.Label>Petal Length</Form.Label>
<Form.Control
type="text"
name="petalLen"
value={this.state.petalLen}
onChange={this.handleOnChange}
placeholder="Petal Length"
/>
</Col>
<Col>
<Form.Group>
<Form.Label>Petal Width</Form.Label>
<Form.Control
type="text"
name="petalWid"
value={this.state.petalWid}
onChange={this.handleOnChange}
placeholder="Petal Width"
/>
</Form.Group>
</Col>
<Col>
<Form.Group>
<Form.Label>Sepal Length</Form.Label>
<Form.Control
type="text"
name="sepalLen"
value={this.state.sepalLen}
onChange={this.handleOnChange}
placeholder="Sepal Length"
/>
</Form.Group>
</Col>
<Col>
<Form.Group>
<Form.Label>Sepal Width</Form.Label>
<Form.Control
type="text"
name="sepalWid"
value={this.state.sepalWid}
onChange={this.handleOnChange}
placeholder="Sepal Width"
/>
</Form.Group>
</Col>
</Row>
<Button variant="primary" type="submit" onClick={this.handleSubmit}>
Submit
</Button>
</Container>
</Form>
</div>
);
}
}
After I hit submit :

settimeout is not working because of React-bootstrap validation

I'm trying to set form validation in React-bootstrap.
I've just written code in accordance with React-bootstrap document.
https://react-bootstrap.netlify.app/components/forms/#forms-validation
I confirmed validation is activated and data is changed when I push submit button.
But only setTimeout method is not working because of adding React-bootstrap validation code.
I couldn't find where I missed and should fix.
Could you tell me the differences between my code and document.
Also, I add comments to my code to make clearly.
PS: I debugged my code. I found that that code was skipped.
I am investigating causes now.
.then(response => {
if (response.data != null) {
alert('編集完了!')
window.setTimeout(() => {
history.push("/")
}, 1000)
}
})
Before adding code
import axios from 'axios'
import { useEffect, useState } from 'react'
import { Card, Form, Button, Col } from 'react-bootstrap';
import React, { Component } from 'react'
import { BrowserRouter, Route, Link, useHistory } from 'react-router-dom'
import Box from '#material-ui/core/Box';
import { Copyright } from './Copyright';
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome'
import { faList, faHome, faClipboardCheck } from '#fortawesome/free-solid-svg-icons'
export const EditData = (props) => {
const history = useHistory()
const id = props.listNo;
const [dataOne, setDataOne] = useState({});
useEffect(() => {
axios.get("http://localhost:8080/action/edit/" + id).then((response) =>
setDataOne(response.data)
)
}, [])
const handleChange = event => {
setDataOne({ ...dataOne, [event.target.name]: event.target.value });
};
const handleSubmit = event => {
event.preventDefault();
const list = {
listNo: dataOne.listNo,
softwareName: dataOne.softwareName,
saiyouDate: dataOne.saiyouDate,
version: dataOne.version,
shubetu: dataOne.shubetu,
licenseManage: dataOne.licenseManage,
youto: dataOne.youto,
bikou: dataOne.bikou,
authorizer: dataOne.authorizer,
approvalDate: dataOne.approvalDate,
url: dataOne.url
}
axios.post("http://localhost:8080/action/edit/contents", list)
.then(response => {
if (response.data != null) {
alert('編集完了!')
window.setTimeout(() => {
history.push("/")
}, 1000)
}
})
};
return (
<div>
<div className="container">
<Card>
<Card.Header className="text-center" style={{ backgroundColor: '#75A9FF', color: '#FFF' }}>
<FontAwesomeIcon icon={faList} />使用許可ソフトウェアリスト
</Card.Header>
<Form id="listFormId" onSubmit={handleSubmit}>
<Form.Control
required
type="hidden"
name="listNo"
value={dataOne.listNo || ""}
onChange={handleChange}
/>
<Card.Body>
<Form.Row>
<Form.Group as={Col}>
<Form.Label>ソフトウェア名</Form.Label>
<Form.Control
type="text"
name="softwareName"
value={dataOne.softwareName || ""}
onChange={handleChange}
/>
</Form.Group>
</Form.Row>
<Form.Row>
<Form.Group as={Col}>
<Form.Label>採用日</Form.Label>
<Form.Control
type="text"
name="saiyouDate"
value={dataOne.saiyouDate || ""}
onChange={handleChange} />
</Form.Group>
<Form.Group as={Col}>
<Form.Label>バージョン</Form.Label>
<Form.Control
type="text"
name="version"
value={dataOne.version || ""}
onChange={handleChange}
/>
</Form.Group>
</Form.Row>
<Form.Row>
<Form.Group as={Col}>
<Form.Label>種別</Form.Label>
<Form.Control
type="text"
name="shubetu"
value={dataOne.shubetu || ""}
onChange={handleChange} />
</Form.Group>
<Form.Group as={Col}>
<Form.Label>ライセンス</Form.Label>
<Form.Control
type="text"
name="licenseManage"
value={dataOne.licenseManage || ""}
onChange={handleChange} />
</Form.Group>
</Form.Row>
<Form.Row>
<Form.Group as={Col}>
<Form.Label>用途</Form.Label>
<Form.Control
type="text"
name="youto"
value={dataOne.youto || ""}
onChange={handleChange} />
</Form.Group>
<Form.Group as={Col}>
<Form.Label>備考</Form.Label>
<Form.Control
type="text"
name="bikou"
value={dataOne.bikou || ""}
onChange={handleChange} />
</Form.Group>
</Form.Row>
<Form.Row>
<Form.Group as={Col}>
<Form.Label>承認者</Form.Label>
<Form.Control
type="text"
name="authorizer"
value={dataOne.authorizer || ""}
onChange={handleChange} />
</Form.Group>
<Form.Group as={Col}>
<Form.Label>承認日</Form.Label>
<Form.Control
type="text"
name="approvalDate"
value={dataOne.approvalDate || ""}
onChange={handleChange} />
</Form.Group>
</Form.Row>
<Form.Row>
<Form.Group as={Col}>
<Form.Label>URL</Form.Label>
<Form.Control
type="text"
name="url"
value={dataOne.url || ""}
onChange={handleChange} />
</Form.Group>
</Form.Row>
</Card.Body>
<Card.Footer style={{ "textAlign": "right" }}>
<Link to="/">
<Button size="sm" variant="outline-primary" type="button">
<FontAwesomeIcon icon={faHome} />トップ
</Button>
</Link>
<Button size="sm" variant="outline-success" type="submit" style={{ marginLeft: '10px' }} >
<FontAwesomeIcon icon={faClipboardCheck} /> 編集完了
</Button>
</Card.Footer>
</Form>
</Card>
</div>
<Box pt={4} pb={4}>
<Copyright />
</Box>
</div>
)
}
Add react-bootstrap validation
import axios from 'axios'
import { useEffect, useState } from 'react'
import { Card, Form, Button, Col } from 'react-bootstrap';
import React, { Component } from 'react'
import { BrowserRouter, Route, Link, useHistory } from 'react-router-dom'
import Box from '#material-ui/core/Box';
import { Copyright } from './Copyright';
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome'
import { faList, faHome, faClipboardCheck } from '#fortawesome/free-solid-svg-icons'
export const EditData = (props) => {
const [validated, setValidated] = useState(false);//Add
const history = useHistory()
const id = props.listNo;
const [dataOne, setDataOne] = useState({});
useEffect(() => {
axios.get("http://localhost:8080/action/edit/" + id).then((response) =>
setDataOne(response.data)
)
}, [])
const handleChange = event => {
setDataOne({ ...dataOne, [event.target.name]: event.target.value });
};
const handleSubmit = event => {
//Add and Change code
const form = event.currentTarget;
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
setValidated(true);
} else {
const list = {
listNo: dataOne.listNo,
softwareName: dataOne.softwareName,
saiyouDate: dataOne.saiyouDate,
version: dataOne.version,
shubetu: dataOne.shubetu,
licenseManage: dataOne.licenseManage,
youto: dataOne.youto,
bikou: dataOne.bikou,
authorizer: dataOne.authorizer,
approvalDate: dataOne.approvalDate,
url: dataOne.url
}
axios.post("http://localhost:8080/action/edit/contents", list)
.then(response => {
if (response.data != null) {
alert('編集完了!')
window.setTimeout(() => {
history.push("/")
}, 1000)
}
})
}
};
return (
<div>
<div className="container">
<Card>
<Card.Header className="text-center" style={{ backgroundColor: '#75A9FF', color: '#FFF' }}>
<FontAwesomeIcon icon={faList} />使用許可ソフトウェアリスト
</Card.Header>
{// add novalidate and required
}
<Form id="listFormId" noValidate validated={validated} onSubmit={handleSubmit}>
<Form.Control
required
type="hidden"
name="listNo"
value={dataOne.listNo || ""}
onChange={handleChange}
/>
<Card.Body>
<Form.Row>
<Form.Group as={Col}>
<Form.Label>ソフトウェア名</Form.Label>
<Form.Control
required
type="text"
name="softwareName"
value={dataOne.softwareName || ""}
onChange={handleChange}
/>
</Form.Group>
</Form.Row>
<Form.Row>
<Form.Group as={Col}>
<Form.Label>採用日</Form.Label>
<Form.Control
required
type="text"
name="saiyouDate"
value={dataOne.saiyouDate || ""}
onChange={handleChange} />
</Form.Group>
<Form.Group as={Col}>
<Form.Label>バージョン</Form.Label>
<Form.Control
required
type="text"
name="version"
value={dataOne.version || ""}
onChange={handleChange}
/>
</Form.Group>
</Form.Row>
<Form.Row>
<Form.Group as={Col}>
<Form.Label>種別</Form.Label>
<Form.Control
required
type="text"
name="shubetu"
value={dataOne.shubetu || ""}
onChange={handleChange} />
</Form.Group>
<Form.Group as={Col}>
<Form.Label>ライセンス</Form.Label>
<Form.Control
required
type="text"
name="licenseManage"
value={dataOne.licenseManage || ""}
onChange={handleChange} />
</Form.Group>
</Form.Row>
<Form.Row>
<Form.Group as={Col}>
<Form.Label>用途</Form.Label>
<Form.Control
required
type="text"
name="youto"
value={dataOne.youto || ""}
onChange={handleChange} />
</Form.Group>
<Form.Group as={Col}>
<Form.Label>備考</Form.Label>
<Form.Control
type="text"
name="bikou"
value={dataOne.bikou || ""}
onChange={handleChange} />
</Form.Group>
</Form.Row>
<Form.Row>
<Form.Group as={Col}>
<Form.Label>承認者</Form.Label>
<Form.Control
required
type="text"
name="authorizer"
value={dataOne.authorizer || ""}
onChange={handleChange} />
</Form.Group>
<Form.Group as={Col}>
<Form.Label>承認日</Form.Label>
<Form.Control
required
type="text"
name="approvalDate"
value={dataOne.approvalDate || ""}
onChange={handleChange} />
</Form.Group>
</Form.Row>
<Form.Row>
<Form.Group as={Col}>
<Form.Label>URL</Form.Label>
<Form.Control
required
type="text"
name="url"
value={dataOne.url || ""}
onChange={handleChange} />
</Form.Group>
</Form.Row>
</Card.Body>
<Card.Footer style={{ "textAlign": "right" }}>
<Link to="/">
<Button size="sm" variant="outline-primary" type="button">
<FontAwesomeIcon icon={faHome} />トップ
</Button>
</Link>
<Button size="sm" variant="outline-success" type="submit" style={{ marginLeft: '10px' }} >
<FontAwesomeIcon icon={faClipboardCheck} /> 編集完了
</Button>
</Card.Footer>
</Form>
</Card>
</div>
<Box pt={4} pb={4}>
<Copyright />
</Box>
</div>
)
}
I resolved that Error in the following way.
I wrote event.preventDefault(); outside if statement like that.
event.preventDefault();
//Add and Change code
const form = event.currentTarget;
if (form.checkValidity() === false) {
event.stopPropagation();
setValidated(true);
} else {

React. Form validation

I have a multistep form for signing up. What is the easiest and the best approach for form validation? What should I use? Is it alright to use Formik for that? Could you suggest to me what to do?
Here is one of the forms:
return(
<Container>
<Row className="justify-content-center">
<Col md="8">
<Card border="dark">
<Card.Title className="text-center">New User</Card.Title>
<Card.Body>
<Form>
<Form.Group controlId="formGridFirstName">
<Form.Label>First Name</Form.Label>
<Form.Control type="text" value={formValues.firstName} onChange={handleChange('firstName')} />
</Form.Group>
<Form.Group controlID="formGridLastName">
<Form.Label>Last Name</Form.Label>
<Form.Control type="text" value={formValues.lastName} onChange={handleChange('lastName')} />
</Form.Group>
<Form.Group controlID="formGridEmail">
<Form.Label>Email</Form.Label>
<Form.Control type="email" value={formValues.email} onChange={handleChange('email')} />
</Form.Group>
<Form.Group controlId="formGridPassword">
<Form.Label>Password</Form.Label>
<Form.Control type="password" value={formValues.password} onChange={handleChange('password')} />
</Form.Group>
<Form.Group controlId="formGridPhone">
<Form.Label>Phone</Form.Label>
<Form.Control type="tel" value={formValues.phone} onChange={handleChange('phone')} />
</Form.Group>
<Button variant="light" type="submit" size="lg" onClick={redirectToHome}>Cancel</Button>
<Button variant="primary" type="submit" size="lg" onClick={saveAndContinue}>Next</Button>
</Form>
</Card.Body>
</Card>
</Col>
</Row>
</Container>
);
};
You can use Formik and a Yup for validation schema:
https://formik.org/docs/api/formik#validationschema-schema----schema
npm links:
https://www.npmjs.com/package/formik
https://www.npmjs.com/package/yup
It will look like this:
export default function MyForm() {
const initValues = {
firstName: "",
lastName: "",
email: "",
password: "",
phone: ""
};
const schema = Yup.object().shape({
firstName: Yup.string(),
lastName: Yup.string(),
email: Yup.string().email("Email format is invalid."),
password: Yup.string()
.required("No password provided.")
.min(8, "Password is too short - should be 8 chars minimum.")
.matches(/[a-zA-Z]/, "Password can only contain Latin letters."),
phone: Yup.string().phone(" ")
});
return (
<Formik validationSchema={schema} initialValues={initValues}>
{props => {
const {
values,
touched,
errors,
isSubmitting,
handleChange,
setFieldTouched
} = props;
return (
<Container>
<Row className="justify-content-center">
<Col md="8">
<Card border="dark">
<Card.Title className="text-center">New User</Card.Title>
<Card.Body>
<Form>
<Form.Group controlId="formGridFirstName">
<Form.Label>First Name</Form.Label>
<Form.Control
name="firstName"
type="text"
value={values.firstName}
onChange={handleChange}
setFieldTouched={setFieldTouched}
errors={errors}
/>
</Form.Group>
<Form.Group controlID="formGridLastName">
<Form.Label>Last Name</Form.Label>
<Form.Control
name="lastName"
type="text"
value={values.lastName}
onChange={handleChange}
setFieldTouched={setFieldTouched}
errors={errors}
/>
</Form.Group>
<Form.Group controlID="formGridEmail">
<Form.Label>Email</Form.Label>
<Form.Control
name="email"
type="email"
value={values.email}
onChange={handleChange}
setFieldTouched={setFieldTouched}
errors={errors}
/>
</Form.Group>
<Form.Group controlId="formGridPassword">
<Form.Label>Password</Form.Label>
<Form.Control
name="password"
type="password"
value={values.password}
onChange={handleChange}
setFieldTouched={setFieldTouched}
errors={errors}
/>
</Form.Group>
<Form.Group controlId="formGridPhone">
<Form.Label>Phone</Form.Label>
<Form.Control
name="phone"
type="tel"
value={values.phone}
onChange={handleChange}
setFieldTouched={setFieldTouched}
errors={errors}
/>
</Form.Group>
<Button
variant="light"
type="submit"
size="lg"
onClick={redirectToHome}
>
Cancel
</Button>
<Button
variant="primary"
type="submit"
size="lg"
onClick={saveAndContinue}
>
Next
</Button>
</Form>
</Card.Body>
</Card>
</Col>
</Row>
</Container>
);
}}
</Formik>
);
}
But you should change also your Form.Control component:
Add
import { ErrorMessage, getIn } from "formik";
const error = getIn(props.errors, props.name);
and add to your Input these attributes
onChange={(e) => {setFieldTouched("firstName");handleChange(e);}
error={error}
and Error to show
<Error component="div" name={props.name} />
I would suggest adding your own validators and bundling inputs that are of the same type. For example First Name and Last Name are both strings so you can have a validator for string types. You could do it like this
//validator.js
const stringValidator = (value) => {
if(isEmpty(value)){
return { isValid: false, errors: ["Field cannot be blank"] }
}
return { isValid: true, errors: [] }
}
const config = {
firstName: stringValidator,
lastName: stringValidator,
email: emailValidator,
cellphone: cellphoneValidator,
password: passwordValidator
}
const getValidator = (questionId) => config[questionId];
export default (questionId, value) => {
const validate = getValidator(questionId);
return validate(value)
}
...
// Form.js class
answerQuestion(questionId){
return (e) => {
const answer = e.target.value;
const validation = validate(questionId, answer)
const { errors } = validation;
let { fields } = this.state;
fields[questionId] = { errors, value, label: field.label }
this.setState({ fields })
}
}
...
<Form>
{this.state.fields.map( field => {
return(
<Form.Group>
<Form.Label>{field.label}</Form.Label>
<Form.Control type="text" value={field.value} onChange={this.answerQuestion(field.questionId)} />
{field.errors.map(err => <span>{err}</span>}
</Form.Group>
)
}
</Form>

How to append inputs with formik in react

So this may be something simple but I'm hitting a roadblock. I want to take in a form input but can't seem to figure out how to append the value correctly so its appending string is captured.
I'm using Formik with yup in react.
<InputGroup>
<Field
id="appended-input"
name="domain_url"
type="text"
value={values.domain_url}
className={
"form-control" +
(errors.domain_url && touched.domain_url
? " is-invalid"
: "")
}
/>
<ErrorMessage
name="domain_url"
component="div"
className="invalid-feedback"
/>
<InputGroupAddon addonType="append">
.localhost
</InputGroupAddon>
</InputGroup>
Any help would be appreciated. I just want to get the .localhost to be automatically added to the input items. for this field. I thought I could do something like value=({values.domain_url} + ".localhost") but that didn't seem to work and as you may already tell I am very new to javascript.
Thank you!
Full code below, I'm also having issues with datepicker displaying within the formik state, and then there's how to even get the values to push to my getTenant(function) to be passed to my api.
static propTypes = {
addTenant: PropTypes.func.isRequired,
};
onSubmit = (values) => {
values.preventDefault();
this.props.addTenant(values);
};
render() {
const {
domain_url,
schema_name,
name,
config,
} = this.state;
const TenantSchema = Yup.object().shape({
domain_url: Yup.string()
.max(255, "Must be shorter than 255 characters")
.required("Client URL header is required"),
schema_name: Yup.string()
.max(255, "Must be shorter than 255 characters")
.required("Client db name is required"),
name: Yup.string()
.max(255, "Must be shorter than 255 characters")
.required("Client name is required"),
});
return (
<div className={s.root}>
<Formik
initialValues={{
domain_url: "",
schema_name: "",
client_name: "",
config: [
{
date: "",
Tenant_description: "",
},
],
}}
// validationSchema={TenantSchema} this is commented off because it breaks
submittions
onSubmit={(values, { setSubmitting, resetForm }) => {
setSubmitting(true);
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
resetForm();
setSubmitting(false);
}, 100);
}}
//onSubmit={onSubmit}
>
{({
values,
errors,
status,
touched,
handleBlur,
handleChange,
isSubmitting,
setFieldValue,
handleSubmit,
props,
}) => (
<FormGroup>
<Form onSubmit={handleSubmit}>
<legend>
<strong>Create</strong> Tenant
</legend>
<FormGroup row>
<Label for="normal-field" md={4} className="text-md-right">
Show URL
</Label>
<Col md={7}>
<InputGroup>
<Field
id="appended-input"
name="domain_url"
type="text"
value={values.domain_url}
onSubmit={(values) => {
values.domain_url = values.domain_url + ".localhost";
}} //this isn't working
className={
"form-control" +
(errors.domain_url && touched.domain_url
? " is-invalid"
: "")
}
/>
<ErrorMessage
name="domain_url"
component="div"
className="invalid-feedback"
/>
<InputGroupAddon addonType="append">
.localhost
</InputGroupAddon>
</InputGroup>
</Col>
</FormGroup>
<FormGroup row>
<Label for="normal-field" md={4} className="text-md-right">
Database Name
</Label>
<Col md={7}>
<Field
name="schema_name"
type="text"
className={
"form-control" +
(errors.schema_name && touched.schema_name
? " is-invalid"
: "")
}
/>
<ErrorMessage
name="schema_name"
component="div"
className="invalid-feedback"
/>
</Col>
</FormGroup>
<FormGroup row>
<Label for="normal-field" md={4} className="text-md-right">
Name
</Label>
<Col md={7}>
<Field
name="name"
type="text"
className={
"form-control" +
(errors.name && touched.name
? " is-invalid"
: "")
}
/>
<ErrorMessage
name="name"
component="div"
className="invalid-feedback"
/>
</Col>
</FormGroup>
<FieldArray
name="config"
render={(arrayHelpers) => (
<div>
{values.config.map((config, index) => (
<div key={index}>
<FormGroup row>
<Label
md={4}
className="text-md-right"
for="mask-date"
>
Tenant Description
</Label>
<Col md={7}>
<TextareaAutosize
rows={3}
name={`config.${index}.tenant_description`}
id="elastic-textarea"
type="text"
onReset={values.event_description}
placeholder="Quick description of tenant"
onChange={handleChange}
value={values.tenant_description}
onBlur={handleBlur}
className={
`form-control ${s.autogrow} transition-height` +
(errors.tenant_description &&
touched.tenant_description
? " is-invalid"
: "")
}
/>
<ErrorMessage
name="tenant_description"
component="div"
className="invalid-feedback"
/>
</Col>
</FormGroup>
<FormGroup row>
<Label
for="normal-field"
md={4}
className="text-md-right"
>
Date
</Label>
<Col md={7}>
<DatePicker
tag={Field}
name={`config.${index}.date`}
type="date"
selected={values.date}
value={values.date}
className={
"form-control" +
(errors.date&& touched.date
? " is-invalid"
: "")
}
onChange={(e) =>
setFieldValue("date", e)
}
/>
<ErrorMessage
name="date"
component="div"
className="invalid-feedback"
/>
</Col>
</FormGroup>
</div>
))}
</div>
)}
/>
<div className="form-group">
<button
type="submit"
disabled={isSubmitting}
className="btn btn-primary mr-2"
>
Save Tenant
</button>
<button type="reset" className="btn btn-secondary">
Reset
</button>
</div>
</Form>
<Col md={7}>{JSON.stringify(values)}</Col>
</FormGroup>
)}
</Formik>
</div>
);
}
}
export default connect(null, { addTenant })(TenantForm);
You could use setFieldValue if you want to customize the value
https://jaredpalmer.com/formik/docs/api/formik#setfieldvalue-field-string-value-any-shouldvalidate-boolean--void
You can add onChange
<Field
id="appended-input"
name="domain_url"
type="text"
value={values.domain_url}
onChange={st => {
let value = st.target.value;
let suffix = ".localhost";
let index = value.indexOf(".localhost");
if (index > 0) {
suffix = "";
}
//add suffix 'localhost' if it is not already added
props.setFieldValue("domain_url", value + suffix);
}}
className={
"form-control" +
(errors.domain_url && touched.domain_url ? " is-invalid" : "")
}
/>;
But adding suffix is more preferable on onSubmit:
onSubmit = {(values, actions) => {
console.log('valuesbefore',values)
values.domain_url= values.domain_url+ ".localhost"
console.log('valuesafter',values)
this.props.addTenant(values);
};

Categories