How to make post request with form in React - reactjs

After i filled the inputs and submitted the form, I want to make a POST request with React. When i use fetch outside the handleSubmit function with a static name and job value, it works. But if i use inside the handleSubmit function, it doesn't work. Why? and how can i solve this?
import React from "react";
function CreateUser() {
const handleSubmit = (e) => {
e.preventDefault();
fetch("https://reqres.in/api/users", {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify({
name: `${e.target.name.value}`,
job: `${e.target.job.value}`,
}),
})
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
});
};
return (
<form onSubmit={handleSubmit}>
<label htmlFor="name">Name</label>
<input id="name" name="name" type="text" />
<label htmlFor="job">job</label>
<input id="job" name="job" type="text" />
<input type="submit" value="submit" />
</form>
);
}
export default CreateUser;

Can you check how to use fetch correctly. https://developers.google.com/web/ilt/pwa/working-with-the-fetch-api you need to return response.
Your react code seems fine, not sure how are you trying to handle success and error.
Check following Sandbox which I created using your code.
https://codesandbox.io/s/adoring-breeze-7fx2g?file=/src/App.js

Related

POST request sending an empty object even though console.log is show input values are being captured

When i submit the form, the object shows up as empty in my db.json file even though console.log is showing that i've capture the inputs.
There are no errors that are popping up, but rather once i hit post, it just shows a new object with an unique ID but nothing that was entered into the form was captured.
import React, { useState } from "react";
const blankNewLegend = {
name:"",
image:"",
nickname:"",
legendType:"",
tactAbility:"",
passAbility:"",
ultAbility:"",
season: 0,
likes: 0,
};
function NewLegendForm() {
const[newLegend, setNewLegend] = useState(blankNewLegend)
console.log(newLegend)
function handleChange(e){
console.log(e)
setNewLegend((prev) => ({
...prev,
[e.target.name] : e.target.value
}
));
e.preventDefault();
}
function handleSubmit(e){
e.preventDefault();
console.log(newLegend)
fetch('http://localhost:6004/legends',{
method: "POST",
header: {
"Content-Type": "application/json"
},
body: JSON.stringify(newLegend),
})
.then((res) => {
console.log(res, 'this')
})
}
return (
<div className="new-legend-form">
<h2>Add New Legend</h2>
<form onSubmit={handleSubmit} >
<input type="text" name="name" placeholder="Legend name" value={newLegend.name} onChange={handleChange}/>
<input type="text" name="image" placeholder="Image URL" value={newLegend.image} onChange={handleChange}/>
<input type="text" name="nickname" placeholder="Nickname" value={newLegend.nickname} onChange={handleChange}/>
<input type="text" name="legendType" placeholder="Legend Type" value={newLegend.legendType} onChange={handleChange}/>
<input type="text" name="tactAbility" placeholder="Tactical Ability" value={newLegend.tactAbility} onChange={handleChange}/>
<input type="text" name="passAbility" placeholder="Passive Ability" value={newLegend.passAbility} onChange={handleChange}/>
<input type="text" name="ultAbility" placeholder="Ultimate Ability" value={newLegend.ultAbility} onChange={handleChange}/>
<input type="number" name="season" placeholder="Debut Season" value={newLegend.season} onChange={handleChange}/>
<input type="number" name="likes" placeholder="Likes" value={newLegend.likes} onChange={handleChange}/>
<button type="submit">Add Legend</button>
</form>
<p>{newLegend.name}</p>
</div>
);
}
export default NewLegendForm;
Your database API can't read the content-type. In your fetch statement, change the key "header" to "headers" (i.e. plural), as shown below. You should then see the full json object in your db.json file:
function handleSubmit(e){
e.preventDefault();
console.log(newLegend)
fetch('http://localhost:6004/legends',{
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(newLegend),
})
.then((res) => {
console.log(res, 'this')
})
}

image file isnt being read by react

I am using formData to send details to my backend but somehow my image path isn't being sent.
Post photo
<div className="form-group">
<label className="btn btn-block btn-success">
<input
onChange={handleChange("photo")}
ref={inputRef}
type="file"
name="photo"
accept="image"
placeholder="choose a file"
/>
</label>
</div>
this is the form i am using
Handle change and submit button
const onSubmit = (event) => {
event.preventDefault();
setValues({...values,error:"",loading:true});
createProduct(user._id,token,JSON.stringify(values))
.then(data=>{
if(data.error){
setValues({...values,error:data.error});
}else{
setValues({...values,
name:"",
description:"",
price:"",
photo:"",
stock:"",
createdProduct:data.name,
loading:false});
}
}).then(response=>{
})
.catch(err=>console.log(err));
//
};
const handleChange = name => event => {
const value=name==="photo"?event.target.files[0]:event.target.value;
formData.append(name,value)
setValues({...values,[name]:value});
//
};
And this is the api call to backend
export const createProduct=(userId,token,product)=>{
console.log(product)
return fetch(`${API}/product/create/${userId}`,{
method: "POST",
headers:{
Accept: "application/json",
Authorization: `Bearer ${token}`
},body:product
})
.then(response=>{
return response.json();
})
.catch(err=>console.log(err));
}
The api is working fine with postman , I am using formidable in backend. Some answers from stack made the path of the file have c:\fakepath and so m too confused what to do .
Thanks for help.

POST request in react hook form not fetching the user input

I am working on an address book and I have fetched all the data from this API url:
https://jsonplaceholder.typicode.com/users
The API cannot really be modified, but it should behave "like if" according to this message in the documentation: "resource will not be really updated on the server but it will be faked as if."
I have set up the react hook form but when I submit my form this is what I get in the dev tools tab network? Shouldn't be showing the user inputs at this point instead of empty string for all fields? The id is the only thing that gets updated.
Is there anything wrong with my Submit function or the actual fetch? Is it ok I have the POST fetch in this component where I have my form as well or should be in the same component where I have the GET request?
Would this one be a good way to approach the POST request?
const NewUserForm = () => {
const { register, handleSubmit, formState: { errors } } = useForm();
const onSubmit = () => {
fetch(URL, {
method: 'POST',
body: JSON.stringify({
id:'',
name: '',
email: '',
address1:'',
address2:'',
city:'',
phone:''
}),
headers: {
'Content-type': 'application/json; charset=UTF-8'
},
})
.then((response) => response.json())
.then((json) => console.log(json));
}
return (
<>
<Header>New user</Header>
<FormContainer>
<Form onSubmit={handleSubmit(onSubmit)}>
<input type="text" placeholder="name" {...register("name", { required: true })} />
{errors.name && <span>This field is required</span>}
<input type="text" placeholder="email" {...register("email", { required: true })} />
{errors.email && <span>This field is required</span>}
<input type="text" placeholder="address1"{...register("address1", { required: true })} />
{errors.address1 && <span>This field is required</span>}
<input type="text" placeholder="address2"{...register("address2", { required: true })} />
{errors.address2 && <span>This field is required</span>}
<input type="text" placeholder="city"{...register("city", { required: true })} />
{errors.city && <span>This field is required</span>}
<input type="text" placeholder="phone"{...register("phone", { required: true })} />
{errors.phone && <span>This field is required</span>}
<input type="submit" />
</Form>
</FormContainer>
</>
);
}
Okay, after checking the react-hook-form docs, here is a possible solution:
In the docs, it says that your onSubmit will have a data param:
const onSubmit = (data) => alert(JSON.stringify(data));
Which means that you can use that in your onSubmit too.
Try changing your onSubmit to use the data parameter:
const onSubmit = (data) => {
fetch(URL, {
method: 'POST',
body: JSON.stringify(data),
And revert the change I suggested earlier regarding handleSubmit. This is correct:
<Form onSubmit={handleSubmit(onSubmit)}>

preventDefault() not working on submit in React

I'm currently working in react and have a couple of forms where the onSubmit functions automatically refresh the page even if I use preventDefault(). Im passing the event into the functions as well. Could really use some guidance on why these two forms are having this issue. It hasn't been a problem elsewhere.
Here's the form. Verify is automatically passing e.
<form onSubmit={verify} className='username-password-form'>
<div className='old-password-container'>
<label className='old-password-label'>Current Password:</label>
<input
className='old-password-input'
type='password'
id={`${id}-old-password`}
value={currentPassword}
name='currentPassword'
disabled={disabled}
onChange={(e) => setCurrentPassword(e.target.value)}
/>
<Button className='submit-old' type='submit'>
Submit
</Button>
</div>
</form>
Here's the verify function called onSubmit
const verify = async (e) => {
e.preventDefault();
const user = {
username: user_name,
password: currentPassword,
};
await fetch('http://localhost:3000/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(user),
});
setDisabled(true);
};

Set state on form submit in a functional component

In my react typescript app - I have a login component and a handleLoginRequest function which sets the userMessage value:
function Login() {
let [userMessage, setUserMessage] = useState("");
return (
<form className="form-inline" onSubmit={(e) => {
setUserMessage(handleLoginRequest(e))
}} >
<label className="mr-sm-2">Email address:</label>
<input type="email" className="form-control mb-2 mr-sm-2" placeholder="Enter email" id="email" />
<label className="mr-sm-2">Password:</label>
<input type="password" className="form-control mb-2 mr-sm-2" placeholder="Enter password" id="password" />
<button type="submit" className="btn btn-primary mb-2">Submit</button>
{userMessage}
</form>
);
}
Update: handleLoginRequest is a API request
const handleLoginRequest = (event: any): any => {
event.preventDefault();
const data = {
email: event.target.email.value,
password: event.target.password.value
};
axios.post(`${process.env.REACT_APP_HTTP_PROXY}/api/v1/login`, data)
.then(res => {
console.log(res.data);
return res.data;
})
.catch(err => {
console.log(err);
return err.message;
});
}
Expected behavior:
When the form is submitted, the function setUserMessage(handleLoginRequest(e)) is called. I expect that it update the value of userMessage to login request received.
Actual result:
No change in the value of userMessage
What is the fix here?
Updated answer per the question modification
The issue is stemming from the fact you're trying to setState based on a axios post request. Axios requests are asynchronous, meaning they will happen out of order with the program control flow. Therefore, to solve this issue, it is important you only make a call to setUserMessage when the request is complete.
Example Code:
axios.post(`${process.env.REACT_APP_HTTP_PROXY}/api/v1/login`, data)
.then(res => {
setUserMessage(res.data);
})
.catch(err => {
// Do Something with error response
setUserMessage("Error: Something with the request went wrong.");
});
I will link a codesandbox to demonstrate:
https://codesandbox.io/s/focused-leakey-0jer4

Resources