Appending React form data to local CSV - reactjs

I'm new to react and only have an entry level understanding of coding but need to use it for a project.
I've made a React form using Formik with four simple inputs that are logged as JSON strings when submitted. I would like to be able to send this data to a local CSV but I'm unsure about how to proceed from here. Any pointers would be greatly appreciated.
The code for my form is this:
import React from 'react';
import { Formik } from 'formik';
import { useFormik } from 'formik';
const SignupForm = () => {
const formik = useFormik({
initialValues: {
Username: '',
Address: '',
Postcode: '',
Details: '',
Score: '',
},
onSubmit: values => {
alert(JSON.stringify(values, null, 2));
},
});
return (
<form onSubmit={formik.handleSubmit}>
<label htmlFor="Username">Username</label>
<input
id="Username"
name="Username"
type="text"
onChange={formik.handleChange}
value={formik.values.Username}
/>
<label htmlFor="Address">Address</label>
<input
id="Address"
name="Address"
type="textarea"
onChange={formik.handleChange}
value={formik.values.Address}
/>
<label htmlFor="Postcode">Postcode</label>
<input
id="Postcode"
name="Postcode"
type="text"
onChange={formik.handleChange}
value={formik.values.Postcode}
/>
<label htmlFor="Details">Details</label>
<input
id="Details"
name="Details"
type="textarea"
onChange={formik.handleChange}
value={formik.values.Details}
/>
<label htmlFor="Score">Score</label>
<input
id="Score"
name="Score"
type="text"
onChange={formik.handleChange}
value={formik.values.Score}
/>
<button type="submit">Submit</button>
</form>
);
};
export default SignupForm;

Related

unable to use fetch in formik and post data to api

I was trying to post the formik form data using fetch and mutations. I have created my API using neo4j graphql library and Apollo server now i want to post data into the API using react as frontend.
import './App.css';
import { useFormik } from "formik"
function App() {
const updateNameFetch = async (name,age,sex,weight,smoking,drinking,nationality,birth_type) => {
const query = JSON.stringify({
query: `mutation {
createUsers(input:{
user_name: "${name}"
age: ${age}
sex: "${sex}"
weight: ${weight}
smoking:"${smoking}"
drinking: "${drinking}"
nationality:"${nationality}"
birth_type: "${birth_type}"
}
){
users{
user_name
}
}
}
`
});
const formik = useFormik({
initialValues:{
name:"",
age: "",
sex: "",
weight:"",
smoking:"",
drinking:"",
nationality:"",
birth_type:"",
},
onSubmit:(values) => {
console.log(values.name);
fetch("graphql-newone.herokuapp.com/",{
method: "POST",
headers: {"Content-Type": "application/json"},
body: query,
})
}
})
return (
<div className="App">
<form onSubmit={formik.handleSubmit}>
<div className='input-container'>
<input
id="name"
name="name"
type="text"
placeholder="Name"
onChange={formik.handleChange}
value = {formik.values.name}
/>
<input
id="sex"
name="sex"
type="text"
placeholder="Sex"
onChange={formik.handleChange}
value = {formik.values.sex}
/>
<input
id="age"
name="age"
type="text"
placeholder="Age"
onChange={formik.handleChange}
value = {formik.values.age}
/>
<input
id="weight"
name="weight"
type="text"
placeholder="weight"
onChange={formik.handleChange}
value = {formik.values.weight}
/>
<input
id="smoking"
name="smoking"
type="text"
placeholder="smoking"
onChange={formik.handleChange}
value = {formik.values.smoking}
/>
<input
id="nationality"
name="nationality"
type="text"
placeholder="nationality"
onChange={formik.handleChange}
value = {formik.values.nationality}
/>
<input
id="birth_type"
name="birth_type"
type="text"
placeholder="birth_type"
onChange={formik.handleChange}
value = {formik.values.birth_type}
/>
</div>
<button type="submit">Submit</button>
</form>
</div>
);
}}
export default App;
I am getting this error and unable to rectify it
Line 28:18: React Hook "useFormik" is called in function "updateNameFetch" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word "use" react-hooks/rules-of-hooks
Search for the keywords to learn more about each error.
As it says, you cant use the useFormik hook inside the function
import './App.css';
import { useFormik } from "formik"
function App() {
const postData = async(query)=>{
let res = await fetch("graphql-newone.herokuapp.com/",{
method: "POST",
headers: {"Content-Type": "application/json"},
body: query,
})
let data = await res.json()
console.log(data)
}
const formik = useFormik({
initialValues:{
name:"",
age: "",
sex: "",
weight:"",
smoking:"",
drinking:"",
nationality:"",
birth_type:"",
},
onSubmit:async(values) => {
let query = JSON.stringify({
query: `mutation {
createUsers(input:{
user_name: "${values.name}"
age: ${values.age}
sex: "${values.sex}"
weight: ${values.weight}
smoking:"${values.smoking}"
drinking: "${values.drinking}"
nationality:"${values.nationality}"
birth_type: "${values.birth_type}"
}
){
users{
user_name
}
}
}
`
});
postData(query)
}
})
return (
<div className="App">
<form onSubmit={formik.handleSubmit}>
<div className='input-container'>
<input
id="name"
name="name"
type="text"
placeholder="Name"
onChange={formik.handleChange}
value = {formik.values.name}
/>
<input
id="sex"
name="sex"
type="text"
placeholder="Sex"
onChange={formik.handleChange}
value = {formik.values.sex}
/>
<input
id="age"
name="age"
type="text"
placeholder="Age"
onChange={formik.handleChange}
value = {formik.values.age}
/>
<input
id="weight"
name="weight"
type="text"
placeholder="weight"
onChange={formik.handleChange}
value = {formik.values.weight}
/>
<input
id="smoking"
name="smoking"
type="text"
placeholder="smoking"
onChange={formik.handleChange}
value = {formik.values.smoking}
/>
<input
id="nationality"
name="nationality"
type="text"
placeholder="nationality"
onChange={formik.handleChange}
value = {formik.values.nationality}
/>
<input
id="birth_type"
name="birth_type"
type="text"
placeholder="birth_type"
onChange={formik.handleChange}
value = {formik.values.birth_type}
/>
</div>
<button type="submit">Submit</button>
</form>
</div>
);
}
export default App;

Formik breaks page layout

I have this code:
import React from "react";
import { useFormik } from 'formik';
const Registration = () => {
const formik = useFormik({
initialValues: {
email: '',
phone: '',
password: ''
}
})
return (
<div className="registration-page">
<form autoComplete="off">
<label htmlFor="email">Email</label>
<input value={formik.values.email}
id="email" type="email" placeholder="Enter your email"
/>
<label htmlFor="phone">Phone</label>
<input value={formik.values.phone}
id="phone" type="phone" placeholder="Enter your phone"
/>
<label htmlFor="email">Password</label>
<input value={formik.values.password}
id="password" type="password" placeholder="Enter your password"
/>
</form>
</div>
)
}
export default Registration;
The const formik part break the page with the message below:
Uncaught TypeError: Cannot read property 'useRef' of null
What can cause this? Remove the formik constant makes the page working fine.

How to use useFormik hook with async await in onSubmit event?

I'm trying to find how to use async-await with useFormik hooks in onSubmit event.
I want to use axios library inside onSubmit event but with async await, but I'm not able to find the way how to use async await inside onSubmit event.
import React from 'react';
import { useFormik } from 'formik';
const SignupForm = () => {
const formik = useFormik({
initialValues: {
firstName: '',
lastName: '',
email: '',
},
onSubmit: values => {
alert(JSON.stringify(values, null, 2));
},
});
return (
<form onSubmit={formik.handleSubmit}>
<label htmlFor="firstName">First Name</label>
<input
id="firstName"
name="firstName"
type="text"
onChange={formik.handleChange}
value={formik.values.firstName}
/>
<label htmlFor="lastName">Last Name</label>
<input
id="lastName"
name="lastName"
type="text"
onChange={formik.handleChange}
value={formik.values.lastName}
/>
<label htmlFor="email">Email Address</label>
<input
id="email"
name="email"
type="email"
onChange={formik.handleChange}
value={formik.values.email}
/>
<button type="submit">Submit</button>
</form>
);
};
The onSubmit event receives a callback function, it can be a normal function or async function:
...
onSubmit: async (values) => {
// await something here...
},
...
Declare your "await" inside onSubmit function, and then call the api using axios after "await" keyword.
EXAMPLE: https://codesandbox.io/s/jovial-wescoff-uh2e3b
CODE:
import React from "react";
import ReactDOM from "react-dom";
import { Formik, Field, Form } from "formik";
import axios from "axios";
const Example = () => (
<div>
<h1>Sign Up</h1>
<Formik
initialValues={{
firstName: "",
lastName: "",
email: "",
password: ""
}}
onSubmit={async (values) => {
const user = await axios.get("https://reqres.in/api/login", {
email: values.email,
password: values.password
});
alert(JSON.stringify(user, null, 2));
}}
>
{({ isSubmitting }) => (
<Form>
<label htmlFor="firstName">First Name</label>
<Field name="firstName" placeholder="Eve" />
<label htmlFor="lastName">Last Name</label>
<Field name="lastName" placeholder="Holt" />
<label htmlFor="email">Email</label>
<Field name="email" placeholder="eve.holt#reqres.in" type="email" />
<label htmlFor="password">Password</label>
<Field name="password" placeholder="cityslicka" type="password" />
<button type="submit" disabled={isSubmitting}>
Submit
</button>
</Form>
)}
</Formik>
</div>
);
ReactDOM.render(<Example />, document.getElementById("root"));

Date object from react-datepicker not getting saved

Apologies in advance for the abomination of a code you are about to see...
I am relatively new to React and programming in general, and I'm trying to create a MERN application with react-hooks-form to streamline the process. The component I have issues with is the editing portion. I was unable to figure out how to handle controlled inputs in hooks-form so I tried to circumvent the problem by using state to store the values in two different states, which I realize defeats the purpose of using hooks-forms.
Everything so far works fine with the exception of the dateOfBirth which is a required field. On submit, however I get a 400 error and says that dateOfBirth is required.
export default function EditMember(props) {
const [date, setDate] = useState(null);
const [member, setMember] = useState({
firstName: '',
lastName: '',
dateOfBirth: null,
gender: '',
address: '',
phoneNumber: ''
})
const onChangeDate = date => {
setDate(date)
}
useEffect(() => {
axios.get(`http://localhost:5000/members/${props.match.params.id}`)
.then(res => {
setMember({
firstName: res.data.firstName,
lastName: res.data.lastName,
dateOfBirth: Date.parse(res.data.dateOfBirth),
address: res.data.address,
phoneNumber: res.data.phoneNumber,
gender: res.data.gender
});
})
}, [])
useEffect(() => {
axios.get(`http://localhost:5000/members/${props.match.params.id}`)
.then(res => {
setDate(res.data.dateOfBirth);
})
}, []);
const { register, handleSubmit } = useForm();
const onSubmitData = data => {
const updatedMember = {
firstName: data.firstName,
lastName: data.lastName,
dateOfBirth: date,
address: data.address,
phoneNumber: data.phoneNumber,
gender: data.gender,
}
axios.post(`http://localhost:5000/members/update/${props.match.params.id}`, updatedMember)
.then(res => console.log(res.data))
}
return (
<form onSubmit={handleSubmit(onSubmitData)}>
<div>
<input
type="text"
name="firstName"
defaultValue={member.firstName}
placeholder="First name"
ref={register}
/>
<input
type="text"
name="lastName"
defaultValue={member.lastName}
placeholder="Last name"
ref={register}
/>
<span>Male</span>
<input
type="radio"
value="Male"
name="gender"
ref={register}
/>
<span>Female</span>
<input
type="radio"
value="Female"
name="gender"
ref={register}
/>
<input
type="text"
name="address"
placeholder="Address"
ref={register}
defaultValue={member.address}
<input
type="text"
name="phoneNumber"
placeholder="Phone Number"
ref={register}
defaultValue={member.phoneNumber}
/>
<DatePicker
selected = {member.dateOfBirth}
onChange = {onChangeDate}
placeholderText="Select date"
/>
<button type="submit">Edit Log</button>
</form>
)
}
Any reason as to why this occurs? Besides that, any insight into how I can refactor the code would be helpful.
In order to use react-datepicker with react-hook-form you need to utilize react-hook-form's Controller component. Reference here: Integrating Controlled Inputs.
The following component declaration illustrates wrapping a react-datepicker DatePicker component in a react-hook-form Controller component. It is registered with react-hook-form using control={control} and then renders the DatePicker in the Controller components render prop.
const { register, handleSubmit, control, setValue } = useForm();
//...
<Controller
name="dateOfBirth"
control={control}
defaultValue={date}
render={() => (
<DatePicker
selected={date}
placeholderText="Select date"
onChange={handleChange}
/>
)}
/>
The DatePicker still needs to control its value using handleChange and a date state, but we can use this same handler to update the value of the registered input for react-hook-form using setValue().
const handleChange = (dateChange) => {
setValue("dateOfBirth", dateChange, {
shouldDirty: true
});
setDate(dateChange);
};
Your full component (without API calls) might look like the following. onSubmitData() is called by react-hook-form's handleSubmit() and here logs the output of the form, including the updated DatePicker value.
Here's a working sandbox.
import React from "react";
import "./styles.css";
import { useForm, Controller } from "react-hook-form";
import DatePicker from "react-datepicker";
export default function App() {
return (
<div className="App">
<EditMember />
</div>
);
}
function EditMember() {
const { register, handleSubmit, control, setValue } = useForm();
const [date, setDate] = React.useState(new Date(Date.now()));
const onSubmitData = (data) => {
console.log(data);
// axis.post(
// `http://localhost:5000/members/update/${props.match.params.id}`,
// data).then(res => console.log(res.data))
}
const handleChange = (dateChange) => {
setValue("dateOfBirth", dateChange, {
shouldDirty: true
});
setDate(dateChange);
};
return (
<div>
<form onSubmit={handleSubmit(onSubmitData)}>
<input
type="text"
name="firstName"
placeholder="First name"
ref={register}
/>
<input
type="text"
name="lastName"
placeholder="Last name"
ref={register}
/>
<span>Male</span>
<input type="radio" value="Male" name="gender" ref={register} />
<span>Female</span>
<input type="radio" value="Female" name="gender" ref={register} />
<input
type="text"
name="address"
placeholder="Address"
ref={register}
/>
<input
type="text"
name="phoneNumber"
placeholder="Phone Number"
ref={register}
/>
<Controller
name="dateOfBirth"
control={control}
defaultValue={date}
render={() => (
<DatePicker
selected={date}
placeholderText="Select date"
onChange={handleChange}
/>
)}
/>
<button type="submit">Edit Log</button>
</form>
</div>
);
}
Output
//Output
Object {firstName: "First", lastName: "Last", gender: "Male", address: "Addy", phoneNumber: "fon"…}
firstName: "First"
lastName: "Last"
gender: "Male"
address: "Addy"
phoneNumber: "fon"
dateOfBirth: Wed Aug 19 2020 17:20:12 GMT+0100 (BST)
I did eventually figure out what was wrong. There was a typo in the update route that blocked the field from being recorded. I was able to get it working with pretty much the exact same code.
My apologies for not going through them thoroughly.

Submitting Formik form data to firebase database in react

I am trying to figure out how to send form data form a Formik form to a Firebase database in my react app.
I have a form as follows:
import React from 'react'
import { Link } from 'react-router-dom'
// import { Formik } from 'formik'
import { Formik, Form, Field, ErrorMessage, withFormik } from 'formik';
import * as Yup from 'yup';
import { Badge, Button, Col, Feedback, FormControl, FormGroup, FormLabel, InputGroup } from 'react-bootstrap';
import Select from 'react-select';
import firebase from '../../../firebase';
const style1 = {
width: '60%',
margin: 'auto'
}
const style2 = {
paddingTop: '2em',
}
const style3 = {
marginRight: '2em'
}
const style4 = {
display: 'inline-block'
}
const options = [
{ value: 'author', label: 'Author' },
{ value: 'reviewer', label: 'Reviewer' },
];
class Basic extends React.Component {
state = {
selectedOption: null,
}
handleChange = (selectedOption) => {
this.setState({ selectedOption });
console.log(`Option selected:`, selectedOption);
}
render() {
const { selectedOption } = this.state;
return (
<Formik
initialValues={{
firstName: '',
lastName: '',
email: '',
password: '',
confirmPassword: '',
selectedOption: null
}}
validationSchema={Yup.object().shape({
firstName: Yup.string()
.required('First Name is required'),
lastName: Yup.string()
.required('Last Name is required'),
email: Yup.string()
.email('Email is invalid')
.required('Email is required'),
selectedOption: Yup.string()
.required('It will help us get started if we know a little about your background'),
password: Yup.string()
.min(6, 'Password must be at least 6 characters')
.required('Password is required'),
confirmPassword: Yup.string()
.oneOf([Yup.ref('password'), null], 'Passwords must match')
.required('Confirm Password is required')
})}
// onSubmit={fields => {
// alert('SUCCESS!! :-)\n\n' + JSON.stringify(fields, null, 5))
// }}
// onSubmit={handleSubmit}
render={({ errors, status, touched }) => (
<Form style={style1}>
<h1 style={style2}>Get Started</h1>
<div className="form-group">
<label htmlFor="firstName">First Name</label>
<Field name="firstName" type="text" className={'form-control' + (errors.firstName && touched.firstName ? ' is-invalid' : '')} />
<ErrorMessage name="firstName" component="div" className="invalid-feedback" />
</div>
<div className="form-group">
<label htmlFor="lastName">Last Name</label>
<Field name="lastName" type="text" className={'form-control' + (errors.lastName && touched.lastName ? ' is-invalid' : '')} />
<ErrorMessage name="lastName" component="div" className="invalid-feedback" />
</div>
<div className="form-group">
<label htmlFor="email">Email</label>
<Field name="email" type="text" placeholder="Please use your work email address" className={'form-control' + (errors.email && touched.email ? ' is-invalid' : '')} />
<ErrorMessage name="email" component="div" className="invalid-feedback" />
</div>
<div className="form-group">
<label htmlFor="password">Password</label>
<Field name="password" type="password" className={'form-control' + (errors.password && touched.password ? ' is-invalid' : '')} />
<ErrorMessage name="password" component="div" className="invalid-feedback" />
</div>
<div className="form-group">
<label htmlFor="confirmPassword">Confirm Password</label>
<Field name="confirmPassword" type="password" className={'form-control' + (errors.confirmPassword && touched.confirmPassword ? ' is-invalid' : '')} />
<ErrorMessage name="confirmPassword" component="div" className="invalid-feedback" />
</div>
<div className="form-group">
<label htmlFor="selectedOption">Which role best describes yours?</label>
<Select
value={selectedOption}
onChange={this.handleChange}
options={options}
/>
</div>
<div className="form-group" >
<label htmlFor="consent">By registering you accept the <Link to={'/Terms'}>Terms of Use</Link> and <Link to={'/Privacy'}>Privacy Policy</Link> </label>
</div>
<div className="form-group">
<Button variant="outline-primary" type="submit" style={style3} id="submitRegistration">Register</Button>
</div>
</Form>
)}
/>
);
}
}
export default Basic;
I have a database in firebase (cloud firestore) with a collection called Registrations that has fields named the same as each of these form fields.
I have spent the day following tutorials that seem to be made for react before Formik. There's not much point to showing all the things I've tried and failed at for the day - they're clearly not written with Formik in mind. I can't find a way to write the onSubmit so that Formik can give the data to Firebase.
Has anyone found a current tutorial or know how to do this?
I've used Formik and Firebase in this Open-Source React project. Maybe this is what you're looking for :)
Expertizo React Native Kit

Resources