Axios post request of form data send nothing - reactjs

I need to send form data to my database with an Axios post request, but nothing is sent.
The data I need is what is in movieId input.
Maybe the formData.append is not well written ?
const { register, handleSubmit } = useForm();
const onSubmit = data => {
const formData = new FormData();
formData.append('movieId', data.movieId);
axios.post("http://localhost:5000/addMovie", formData)
.then(response => {
console.log("Status: ", response.status);
console.log("Data: ", response.data);
}).catch(error => {
console.error('Something went wrong!', error);
});
}
return (
<div id="ModalBackground">
<div id="ModalContainer">
<button id= "closeModal" onClick= {() => {closeModal(false)}}>X</button>
<h1 id= "formTitle">Numéro du film</h1>
<form onSubmit={handleSubmit(onSubmit)} id="addMovieForm">
<input type="text" id="movieId" {...register("movieId")} required></input>
<input id= "submit" type="submit" value="Ajouter !"></input>
</form>
</div>
</div>
);
}
export default Modal```

Something is wrong there, i saw you have something specific for the handle submit, so you need to cast your call differently. Because when you do directly onSubmit={handleSubmit(onSubmit)} you are calling directly this method on every render/update
<form onSubmit={handleSubmit(onSubmit)} id="addMovieForm"
<form onSubmit={() => handleSubmit(onSubmit)} id="addMovieForm">
// if you wish to cast the event aswell
<form onSubmit={e => handleSubmit(e,onSubmit)} id="addMovieForm">

I use react hook form (https://react-hook-form.com/get-started), and the doc say that :
const { register, handleSubmit, watch, formState: { errors } } = useForm();
const onSubmit = data => console.log(data);
console.log(watch("example")); // watch input value by passing the name of it
return (
/* "handleSubmit" will validate your inputs before invoking "onSubmit" */
<form onSubmit={handleSubmit(onSubmit)}>```
So I don't know what I have to do xD

Change onSubmit={handleSubmit(onSubmit)} to onSubmit={handleSubmit} as the former is supported in HTML but not in React.
<form onSubmit={handleSubmit} id="addMovieForm">
Add a name attribute to the input field so that the key value pair for this particular input field can be stored inside FormData. This eliminates the formData.append step inside handleSubmit().
<input type="text" id="movieId" name="movieId" required></input>
You need to specify Content-Type: multipart/form-data inside the header of the POST request.
const handleSubmit = (e) => {
e.preventDefault();
// Passing form element (e.target) populates the FormData object with the names and values of the fields inside it.
const formData = new FormData(e.target);
// formData.append("movieId", data.movieId);
// To check formData because simply console.log(formData) won't work
for (let item of formData) {
console.log(item);
}
axios
.post("http://localhost:5000/addMovie", formData, {
headers: { "Content-Type": "multipart/form-data" },
})
.then((response) => {
console.log("Status: ", response.status);
console.log("Data: ", response.data);
})
.catch((error) => {
console.error("Something went wrong!", error);
});
};

Related

FormData not working with Axios Post request - MERN react Js

I've been trying to make a post request to my server(Node Js+Mongodb which runs on localhost too). Axios.post works properly on the client code, however when i try to use formData it doesn't. I can't seem to find any reason why it's not working.
It leaves no error on the console(which makes it more frustrating).
Here is the client code:
someone pls point me to what I might be doing wrong.
import React, { useState } from 'react'
import Axios from 'axios'
export default function InputData() {
const [inputName, setInputName] = useState("")
const [inputAge, setInputAge] = useState(0)
const [inputEmail, setInputEmail] = useState("")
const [userImage, setUserImage] = useState("")
const [info,setInfo] = useState("")
var bodyFormData = new FormData();
bodyFormData.append('name', inputName);
bodyFormData.append('age', inputAge);
bodyFormData.append("email", inputEmail)
const createUser = () => {
Axios.post("http://localhost:3008/createUser",
bodyFormData , { headers: { 'Content-Type': 'multipart/form-data' } }).then(function (response) {
//handle success
console.log(response);
}).catch(function (response) {
//handle error
console.log(response);
});
}
return (
<div>
<form onSubmit={createUser} encType="multipart/form-data">
<div>
<input type="text" placeholder='enter name' value={inputName} width={400} onChange={(e) => setInputName(e.target.value)} /><br/>
<input type="number" placeholder='enter age' width={400} value={inputAge} onChange={(e) => setInputAge(e.target.value)} /><br/>
<input type="email" placeholder='enter e-mail' width={400} value={inputEmail} onChange={(e) => setInputEmail(e.target.value)} /><br />
<button>Submit</button>
</div>
</form>
</div>
)
}
axios: "^0.27.2",
react: "^18.2.0"
Couple of points:
You're probably not seeing any errors (output) in the console because you're submitting the form. You can change your onSubmit handler to include preventDefault:
const createUser = (e) => {
Axios.post("http://localhost:3000/createUser", bodyFormData, { headers: { 'Content-Type': 'multipart/form-data' } })
.then(console.log)
.catch(console.error);
e.preventDefault();
}
You can also keep it as is and see the previous output by persisting the logs of your browse across requests, in Firefox this checkbox:
You should add method=post to your form
I think you will receive all the data from the event [createUser method] on submitting the form, Try removing the header If you still have problem try as below, If you still have the problem check the server side Post method Params
let data = { name: inputName, age: inputAge, email: inputEmail }
Axios.post("http://localhost:3008/createUser",data )
.then(function (response) { console.log(response); })
.catch(function (response) { console.log(response); });

React Bootstrap reset form after submit

Hello I am trying to setup a contact form with React Bootstrap in a React/Next.js app. How would I reset the form after submitting it? When I added a reset handle the validation did not work anymore.
// Form validation
const [validated, setValidated] = useState(false);
// Thank you Message
const [thankYouMessage, setThankYouMessage] = useState(false);
// Form submit handler
async function handleSubmit(e) {
e.preventDefault();
e.stopPropagation();
const formData = new FormData();
Array.from(e.currentTarget.elements).forEach((field) => {
if (!field.name) return;
formData.append(field.name, field.value);
});
await fetch(
"https://domain.tld/wp-json/contact-form-7/v1/contact-forms/1234/feedback",
{
body: formData,
method: "POST",
}
)
.then((response) => response.json())
.then((response) => {
if (response.status === "mail_sent") {
setThankYouMessage(!thankYouMessage);
} else if (response.status === "mail_failed") {
alert("Message failed to send.");
}
});
setValidated(true);
}
This is the form:
<div>
<Form
noValidate
validated={validated}
onSubmit={handleSubmit}
>
<Form.Group controlId="your-name">
<Form.Control
required
type="text"
placeholder="Your name"
name="your-name"
/>
<Form.Control.Feedback type="invalid">
Please enter your name
</Form.Control.Feedback>
</Form.Group>
<Form.Group controlId="your-email">
<Form.Control
required
type="email"
placeholder="Your email address"
name="your-email"
/>
<Form.Control.Feedback type="invalid">
Please enter your email
</Form.Control.Feedback>
</Form.Group>
<Form.Group controlId="your-message">
<Form.Control
as="textarea"
cols={30}
rows={6}
placeholder="Write your message..."
name="your-message"
/>
</Form.Group>
<Button type="submit" variant="primary" size="lg">
Send Message
<span></span>
</Button>
</Form>
<Alert
variant="success"
className={thankYouMessage ? "d-block mt-3" : "d-none"}
>
Thank you for your message. It has been sent.
</Alert>
</div>
I have tried setting up a reset handle with useRef() but it did not work:
const formRef = useRef(null);
const handleReset = () => {
formRef.current.reset();
setValidated(false);
};
Then on the form added ref={formRef} and right after setValidated(true); I did handleReset(); but then the validation does not work anymore.
Any suggestions about this are welcome and any comments on the code as well!
Here's an gif of what happens when adding ref={formRef} to the Form tag and:
const formRef = useRef();
const handleReset = () => {
formRef.current.reset();
setValidated(false);
};
and in the fetch:
.then((response) => response.json())
.then((response) => {
if (response.status === "mail_sent") {
setThankYouMessage(!thankYouMessage);
handleReset();
} else if (response.status === "mail_failed") {
alert("Message failed to send.");
}
});
From what I understand, you want to get response first before resetting? e.preventDefault() is preventing the form from resetting, but by removing that, the page just reloads immediately without waiting for the response. If that is the issue that you're facing, then there are a few solutions:
Use reload (just reloads the current document).
.then((response) => {
if (response.status === "mail_sent") {
setThankYouMessage(!thankYouMessage);
} else if (response.status === "mail_failed") {
alert("Message failed to send.");
}
location.reload();
});
Use submit (just submits form without sending submit event or form validation but this is fine because you have already validated it previously).
const formRef = useRef(null);
...
.then((response) => {
if (response.status === "mail_sent") {
setThankYouMessage(!thankYouMessage);
} else if (response.status === "mail_failed") {
alert("Message failed to send.");
}
formRef.current.submit();
});
...
<Form
noValidate
validated={validated}
onSubmit={handleSubmit}
ref={formRef}
>
Use requestSubmit (same as clicking the submit button). EventListener is needed here because essentially, what you want is to disable default action by calling preventDefault first, then enable default action again after getting response. Unfortunately, there is no such convenient enableDefault function.
The flow is like this:
addEventListener with preventDefault is called (now any button clicks will not reset the form)
Fill the form and click submit button
Fetch and received response
removeEventListener with preventDefault is called (now any button clicks will reset the form)
call requestSubmit to submit the form as if the submit button is clicked, which will reset the form
const formRef = useRef(null);
...
// useCallback is needed here instead of a normal function because
// formRef will be updated every time onChange occurs because react renders again
// which will cause addEventListener/removeEventListener to not work as expected
const stopReset = useCallback((event) => {
event.preventDefault();
// stopPropagation will prevent form validation but if you really need it here
// then you need to add another event listener for handleSubmit in useEffect
// and you can remove onSubmit={handleSubmit} in Form
// event.stopPropagation();
}, []);
useEffect(() => {
formRef.current.addEventListener('submit', stopReset);
// Uncomment this only if you need stopPropagation above
// formRef.current.addEventListener('submit', handleSubmit);
},[]); // Add dependencies in the array, leave it blank if you don't have any
async function handleSubmit(e) {
// remove preventDefault and stopPropagation here
const formData = new FormData();
Array.from(e.currentTarget.elements).forEach((field) => {
if (!field.name) return;
formData.append(field.name, field.value);
});
await fetch(
"https://domain.tld/wp-json/contact-form-7/v1/contact-forms/1234/feedback",
{
body: formData,
method: "POST",
}
)
.then((response) => response.json())
.then((response) => {
if (response.status === "mail_sent") {
setThankYouMessage(!thankYouMessage);
} else if (response.status === "mail_failed") {
alert("Message failed to send.");
}
formRef.current.removeEventListener('submit', stopReset);
formRef.current.requestSubmit()
});
setValidated(true);
}
...
<Form
noValidate
validated={validated}
onSubmit={handleSubmit}
ref={formRef}
>
If you want to display your message for awhile before resetting, you can add a timer.
.then(async (response) => {
if (response.status === "mail_sent") {
setThankYouMessage(!thankYouMessage);
} else if (response.status === "mail_failed") {
alert("Message failed to send.");
}
// sleep for 10 seconds
await new Promise(r => setTimeout(r, 10000));
// call whichever method to reset
});

React axios post request does not send the data

I am using react for my app. I am learning post request. I found one dummy api site Mocky where I can test my post request. This is my api link .For post request I used axios. I don't know how the Mocky api works. I made post request. when I console log the input values I can the value.But when I console log the response it seems like it does not get the data. I don't see any where I am making mistake.
Here is my code:
import React, { useState } from 'react';
import { API_URLS } from '../utilities';
import axios from "axios";
export default function CreateAccount() {
const [state, setState] = useState({
"email": ``,
"password": ``,
"loading": false,
"error": ``
});
const onChangeStudent = (e) => {
setState({
...state,
[e.target.id]: e.target.value
});
};
const onSubmit = async (e) => {
e.preventDefault();
console.log(state);
const url = `https://run.mocky.io/v3/15c2b7ec-9f31-4a18-ae60-a7f41e1f39b2`;
const obj = {
"email": state.email,
"password": state.password
};
console.log(obj.email); //I can see the input value
console.log(obj.password);//I can see the input value
axios
.post(url, obj)
.then((res) => {
console.log(res.data); // it does not show the data
console.log(res);
})
.catch((error) => {
setState({
...state,
"error": error
});
});
};
return (
<div>
<form onSubmit={onSubmit}>
<input
type="text"
value={state.name}
onChange={onChangeStudent}
id="email"
required
/>
<input
type="password"
value={state.password}
onChange={onChangeStudent}
id="password"
required
/>
<button
className="btn waves-effect blue lighten-1"
type="submit"
name="action"
disabled={state.loading}
>
{state.loading ? `loading...` : `save`}
</button>
</form>
</div>
);
}
Hi can't seem to find anything wrong with what you are doing.
I tested the below and it worked for me. Try to change from .then to await. Hope this solves your problem. Check in your network tab if your request is successful and if you are sending the body.
try {
const response = await axios.post('https://run.mocky.io/v3/4b95050f-2bcc-4c78-b86e-6cac09372dce', data);
console.log("Response", response);
} catch(e) {
console.error(e);
}

ReactJS Formik, Why is the form not clearing?

I have Form
const TextForm = props => (
<Formik
initialValues = {{
text: '',
target: props.target
}}
onSubmit = {(values, { setSubmitting, resetForm }) => {
if (values.target == 'add') {
Request('POST', {"text":values.text});
resetForm({"text":""});
setSubmitting(false);
}
}}
>
{({
handleChange,
handleSubmit,
values,
}) => (
<form onSubmit={handleSubmit}>
<input type="hidden" name="target"/>
<textarea className={styles.text} value={values.text} name="text" onChange={handleChange}></textarea><br/>
<button type="submit">
Submit
</button>
</form>
)}
</Formik>
);
And data send ok. But the form doesn't clear. Why??
I also try this:
TextForm.setFieldValue('text', '');
But this doesn`t work too.
Check that the following function call is not throwing an exception:
Request('POST', {"text":values.text});
If an exception is being thrown from Request(..), then the subsequent call to resetForm(..) and setSubmitting(..) will be skipped which would be the reason for the problem you're experiencing.
Also, some improvements you might consider would be to make the following changes to your onSubmit handler:
/* Define onSubmit callback as async */
onSubmit = { async (values, { setSubmitting, resetForm }) => {
try {
if(values.target == 'add') {
/*
If request is async or returns a promise, wait
for it before resetting form
*/
await Request('POST', {"text":values.text});
resetForm({"text":""});
}
}
/*
If you want to handle errors here, do so with a
catch block like so:
catch(err) {
handleErrorHereIfYouChose(err);
}
*/
finally {
/*
Always ensure form submit state is reset, even if
unhandled is exception thrown
*/
setSubmitting(false);
}
}}
Me helped values.text = '';
onSubmit = {async (values, { setSubmitting, resetForm }) => {
try {
if (values.target == 'add') {
await fetch('http://localhost:3000/notes', {
headers: {
'Content-Type': 'application/json',
},
method: 'POST',
body: JSON.stringify({"text":values.text}),
});
values.text = '';
}
}
finally {
setSubmitting(false);
}

How to add object attribute using useState (react hook) from different state that is set by children?

I'm new to React and I hope it is not a duplicate question here, somewhere and sorry if my explanation is wrong. So, I got this 'createEvent' panel that has 3 children's; name, start date (comes from a calendar component), end date (also) and details that come from the input text area. I created 'createEvent' panel as a parent that contains states for every data that come from the child. Inside the parent component, I want to create an object that can be sent to the backend. I tried to get data from children and using useState() to give values to the object attributes. If I try to get data using input from parent it works, but not getting input from children and I don't know what to do.
I`ll leave here examples of one child, create Event panel and post request. If I figure out how to do with these examples, I'll know to do it forward.
insert name component
import React, { useState } from 'react';
import './title.style.css';
export default function Title(props) {
const [name, setName] = useState(props.name);
function handlerName(e) {
props.handlerName(e.target.value);
}
return(
<div class="md-form active-cyan active-cyan-2 mb-3">
<input
class="form-control"
type="text"
placeholder={name}
aria-label="Name"
onChange={(e) => {handlerName(e)}}
/>
</div>
);
}
create event panel
import React, { useState, useEffect } from 'react';
import './createEvent.style.css';
import Name from '../input/title.component.js';
import Calendar from '../input/calendar.component.js';
import Details from '../input/details.component.js';
import CardService from '../../service/CardService.js';
export default function CreateEvent() {
const [eventName, setEventName] = useState("");
const [eventStartDate, setEventStartDate] = useState(new Date());
const [eventEndDate, setEventEndDate] = useState(new Date());
const [eventDetails, setEventDetails] = useState("");
const [eventObject, setEventObject] = useState({
"name": "",
"startDate": new Date(),
"endDate": new Date(),
"details": ""
});
async function handleName(name1){
await setEventName(name1);
}
async function handleStartDate(date){
await setEventObject({startDate: date});
}
async function handleEndDate(date){
await setEventObject({endDate: date});
}
async function handleDetails(value){
await setEventObject({details: value});
}
function handleSubmit(e) {
CardService.postEvent(eventObject)
}
return(
<form onSubmit={(e) => handleSubmit(e)}>
<div className="Create-event">
<div>
<Name name={'Insert event name'} handlerName={handleName} />
</div>
<div className="date">
<Calendar type="submit" handlerDate={handleStartDate} date={eventStartDate}/>
</div>
<div className="date">
<Calendar type="submit" handlerDate={handleEndDate} date={eventEndDate}/>
</div>
<div className="text">
<Details type="submit" handleDetails={handleDetails}/>
</div>
<button className="createButton" >
Create
</button>
</div>
</form>
);
}
post request
const CardService = {
postEvent(value1){
fetch("http://localhost:8080/event/ReminderApp/api/v1/event/" ,
{
method: 'POST',
headers: {
"Content-Type" : "application/JSON" ,
},
dataType: "json",
body: JSON.stringify(value1),
})
.then(response => response.json())
.then(json => {console.log(json)
})
.catch(err => {
console.log('Type send failed', err);
});
},
getEvents() {
return fetch('http://localhost:8080/event/ReminderApp/api/v1/event')
.then((response) => response.json())
.then((response) => {
return response;
});
},
deleteEvent(value) {
fetch("http://localhost:8080/event/ReminderApp/api/v1/event/" + value,
{
method: 'DELETE',
})
.catch(err => {
console.log('Type send failed', err);
});
},
};
export default CardService;
I tried to set all createEvent states in handle function and after using useEffect to set all fields from the object, but the app got broken. I tried to setEventObject() inside the handleSubmit function and call CardService.postEvent() but it sent the default object.
What I show you now, it is the last version of my attemps.

Resources