unable to use fetch in formik and post data to api - reactjs

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;

Related

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"));

Appending React form data to local CSV

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;

Not able to see typed text in input using react hooks and controlled components

//The value coming from the input that triggered the event is getting updated in the state but not displaying in the browser, I don't really understand what's happening, I have been using the same method to update the state in my other project
import React, { useState } from "react";
const Register=()=>{
const [user,setUser]=useState({
name:"",
email:"",
password:"",
reenterPassword:""
});
let changeHandler=(e)=>{
const { name, value } = e.target
setUser({
...user,
[name]: value
})
}
return(
<div className="register">
<h1>Register</h1>
<input onChange={changeHandler} name="Username" placeholder="Please Enter Your Name" type="text" defaultValue="" value={user.name}/>
<input onChange={changeHandler} name="Email" placeholder="Enter your Email" type="email" value={user.email}/>
<input onChange={changeHandler} name="Password" placeholder="Create Your Password" type="password" value={user.password}/>
<input onChange={changeHandler} name="ReEnterPassword" placeholder="Re-Enter Your Password" type="password" value={user.reenterPassword}/>
<div className="button">Register</div>
<div>OR</div>
<div className="button">Login</div>
</div>
)
}
export default Register;
[1]: https://i.stack.imgur.com/G8beV.png
there is good answer here about it: https://stackoverflow.com/a/58877875/2091359
you should not use useState like this, you can do useState for each input separately like this:
const [name, setName] = useState('')
const handleChangeName = (e) => {
setName(e.target.value);
}
return(
<div className="register">
<h1>Register</h1>
<input onChange={handleChangeName} name="Username" placeholder="Please Enter Your Name" type="text" value={name}/>
...
or use useReduce
Try this code:
const Register=()=>{
const [user,setUser]=useState({
Username:"",
Email:"",
Password:"",
ReEnterPassword:""
});
let changeHandler=(e)=>{
const { name, value } = e.target
setUser({
...user,
[name]: value
})
}
return (
<div className="register">
<h1>Register</h1>
<input onChange={(e)=>changeHandler(e)} name="Username" placeholder="Please Enter Your Name" type="text" defaultValue="" value={user.name}/>
<input onChange={(e)=>changeHandler(e)} name="Email" placeholder="Enter your Email" type="email" value={user.email}/>
<input onChange={(e)=>changeHandler(e)} name="Password" placeholder="Create Your Password" type="password" value={user.password}/>
<input onChange={(e)=>changeHandler(e)} name="ReEnterPassword" placeholder="Re-Enter Your Password" type="password" value={user.reenterPassword}/>
<div className="button">Register</div>
<div>OR</div>
<div className="button">Login</div>
</div>
);
}
export default Register;
You need to use the same name for the html input attribute too, and try to use callback in the onChange event.

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.

How to make a POST API call in React?

I am creating a react program for front-end which makes a api call when a form is submitted, I want the contents of the form to be sent in JSON format
Back-end code works fine, back-end is written in python and it works fine when I test using postman.
import React, { Component } from "react"
class MainCon extends Component {
constructor() {
super()
this.state = {
systemId: "",
password: "",
systemType: "",
ip: "",
portNumber: "",
sourceAddressTon: "",
sourceAddressNpi: "",
sourceAddress: "",
destinationAddressTon: "",
destinationAddressNpi: "",
destinationAddress: "",
registeredDelivery: "",
dataCoding: "",
shortMessage: "",
id: "",
//isFriendly: false,
messageMethod: "",
//favColor: "blue"
}
this.handleChange = this.handleChange.bind(this)
}
handleChange(event) {
//const {name, value, type, checked} = event.target
// type === "checkbox" ? this.setState({ [name]: checked }) : this.setState({ [name]: value })
const { name, value } = event.target
this.setState({ [name]: value })
}
handleSubmit(event) {
event.preventDefault();
const data = new FormData(event.target);
console.log(event.target);
let object = {}
for (const [key, value] of data.entries()) {
object[key] = value
}
/*
const headers = new Headers();
headers.append('Content-Type', 'application/json');
const options = {
method: 'POST',
headers,
body: JSON.stringify(object),
};
const request = new Request('http://127.0.0.1:5000/api/add_message', options);
const response = fetch(response);
const status = response.status;
if (status === 201) {
this.fetchAll()
}
*/
fetch('http://127.0.0.1:5000/api/add_message/', {
headers: {
'Content-Type': 'application/json',
},
method: 'POST',
body: JSON.stringify(object),
});
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<br />
<label htmlFor="systemId">System ID</label>
<input
type="text"
value={this.state.systemId}
name="systemId"
placeholder="System ID"
onChange={this.handleChange}
/>
<br />
<br />
<label htmlFor="password">Password:</label>
<input
type="text"
value={this.state.password}
name="password"
placeholder="Password"
onChange={this.handleChange}
/>
<br />
<br />
<label htmlFor="systemType">System Type:</label>
<input
type="text"
value={this.state.systemType}
name="systemType"
placeholder="System Type"
onChange={this.handleChange}
/>
<br />
<br />
<label htmlFor="ip">IP:</label>
<input
type="text"
value={this.state.ip}
name="ip"
placeholder="IP"
onChange={this.handleChange}
/>
<br />
<br />
<label htmlFor="portNumber">Port Number:</label>
<input
type="text"
value={this.state.portNumber}
name="portNumber"
placeholder="Port Number"
onChange={this.handleChange}
/>
<br />
<br />
<label htmlFor="sourceAddressTon">Source Address Ton:</label>
<input
type="text"
value={this.state.sourceAddressTon}
name="sourceAddressTon"
placeholder="Source Address Ton"
onChange={this.handleChange}
/>
<br />
<br />
<label htmlFor="sourceAddressNpi">Source Address Npi:</label>
<input
type="text"
value={this.state.sourceAddressNpi}
name="sourceAddressNpi"
placeholder="Source Address Npi"
onChange={this.handleChange}
/>
<br />
<br />
<label htmlFor="sourceAddress">Source Address:</label>
<input
type="text"
value={this.state.sourceAddress}
name="sourceAddress"
placeholder="Source Address"
onChange={this.handleChange}
/>
<br />
<br />
<label htmlFor="destinationAddressTon">Destination Address Ton:</label>
<input
type="text"
value={this.state.destinationAddressTon}
name="destinationAddressTon"
placeholder="Destination Address Ton"
onChange={this.handleChange}
/>
<br />
<br />
<label htmlFor="destinationAddressNpi">Destination Address Npi:</label>
<input
type="text"
value={this.state.destinationAddressNpi}
name="destinationAddressNpi"
placeholder="Destination Address Npi"
onChange={this.handleChange}
/>
<br />
<br />
<label htmlFor="destinationAddress">Destination Address:</label>
<input
type="text"
value={this.state.destinationAddress}
name="destinationAddress"
placeholder="Destination Address"
onChange={this.handleChange}
/>
<br />
<br />
<label htmlFor="registeredDelivery">Registered Delivery:</label>
<input
type="text"
value={this.state.registeredDelivery}
name="registeredDelivery"
placeholder="Registered Delivery"
onChange={this.handleChange}
/>
<br />
<br />
<label htmlFor="dataCoding">Data Coding:</label>
<input
type="text"
value={this.state.dataCoding}
name="dataCoding"
placeholder="Data Coding"
onChange={this.handleChange}
/>
<br />
<br />
<label>
<input
type="radio"
name="messageMethod"
value="randomMessage"
checked={this.state.messageMethod === "randomMessage"}
onChange={this.handleChange}
/> Random Message
</label>
<label>
<input
type="radio"
name="messageMethod"
value="customMessage"
checked={this.state.messageMethod === "customMessage"}
onChange={this.handleChange}
/> Custom Message
</label>
<br />
<br />
<label htmlFor="shortMessage">Short Message:</label>
<textarea
//className="hideDontTakeUpSpace"
value={this.state.shortMessage}
name="shortMessage"
placeholder="Short Message"
onChange={this.handleChange}
/>
<br />
{/* Formik */}
{/**
<label>Favorite Color:</label>
<select
value={this.state.favColor}
onChange={this.handleChange}
name="favColor"
<option value="blue">Blue</option>
<option value="green">Green</option>
<option value="red">Red</option>
<option value="orange">Orange</option>
<option value="yellow">Yellow</option>
</select>
*/}
{/*<h1>{this.state.systemId} {this.state.password}</h1>*/}
<h2>Type of message: {this.state.messageMethod}</h2>
{/*<h2>Your favorite color is {this.state.favColor}</h2>*/}
<button>Submit</button>
</form>
)
}
}
export default MainCon
This is the server side python code
import requests
import json
from flask import Flask, request, jsonify
from jsonDemoNew import getMemberNew
import redis
app = Flask(__name__)
#app.route('/api/add_message', methods=['GET', 'POST'])
def add_message():
if request.method == 'POST':
content = request.json
print request
print content
return jsonify({"Number of messages sent": 123, "Printed status" : 1})
return "Not POST request"
if __name__ == "__main__":
app.run()
I think there is some problem with the headers I am including
I personally prefer to use axios to make POST requests.
npm install axios --save
Just like on postman:
Select the method ('post' in that case)
Select the url ('http://127.0.0.1:5000/api/add_message/')
Send theData in "json form" like:
{
"data": "oktay"
}
And it's done:
const axios = require('axios');
const postIt = (theData) => {
axios({
method: 'post', // THERE GOES THE METHOD
url: 'http://127.0.0.1:5000/api/add_message/', // THERE GOES THE URL
headers: {},
data: theData
})
.then(function (response) {
console.log("The response of the server: "+response.data);
})
.catch(function (error) {
// handle error
console.log(error);
})
.finally(function () {
// always executed
});
}
postIt({
"data" : "oktay"
});

Resources