I have my nodejs expressjs api and my frontend with reactjs. I have different routes to create and post different things but i am struggling to understand how it works. How can i send the data that a i input in my frontend form to my API and store it in my mongodb database?
This is my Register.js component in reactjs:
import React, { useState } from 'react'
const Register = () => {
const [ formData, setFormData ] = useState({
name: '',
email: '',
password: '',
password2: ''
});
const { name, email, password, password2 } = formData;
const onChange = (e) =>
setFormData({ ...formData, [e.target.name]: e.target.value });
return (
<section className="container">
<h1 className="large text-primary">Sign Up</h1>
<p className="lead">
<i className="fas fa-user" /> Create Your Account
</p>
<form className="form" >
<div className="form-group">
<input
type="text"
placeholder="Name"
name="name"
value={name}
onChange={onChange}
/>
</div>
<div className="form-group">
<input
type="email"
placeholder="Email Address"
name="email"
value={email}
onChange={onChange}
/>
<small className="form-text">
</small>
</div>
<div className="form-group">
<input
type="password"
placeholder="Password"
name="password"
value={password}
onChange={onChange}
/>
</div>
<div className="form-group">
<input
type="password"
placeholder="Confirm Password"
name="password2"
value={password2}
onChange={onChange}
/>
</div>
<input type="submit" className="btn btn-primary" value="Register" />
</form>
<p className="my-1">
</p>
</section>
)
}
export default Register
This is my API to register a user:
//@route POST api/users
//@desc Register user
//@access public
router.post('/', [
check('name', 'Name is required')
.not()
.isEmpty(),
check('email', 'Plese include a valid email').isEmail(),
check('password', 'Please enter a password with 6 or more characters').isLength({min:6})
],
async (req, res)=> {
const errors = validationResult(req);
if(!errors.isEmpty()){
return res.status(400).json({ errors:errors.array()}); //400 is for bad requests
}
const { name, email, password } = req.body;
try{
//See if user exists
let user = await User.findOne({ email });
if(user){
return res.status(400).json({ errors: [{ msg:'User already exists' }] });
}
//Get users gravatar
const avatar = gravatar.url(email,{
s:'200',
r:'pg',
d:'mm'
})
user = new User({
name,
email,
avatar,
password
});
//Encrypt password
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(password, salt);
await user.save();
//Return jsonwebtoken -> this for users to be logged in right after registration
const payload = {
user:{
id: user.id
}
}
jwt.sign(
payload,
config.get('jwtSecret'),
{expiresIn: 360000}, //change to 3600 for production
(err, token)=>{
if(err) throw err;
res.json({ token });
}
)
}catch(err){
console.error('err.message');
res.status(500).send('Server Error');
}
});
module.exports = router;
How and where i have to consume my API to send data?
CodePudding user response:
Client Side
Add a function to capture the form's submit event and send the data (as JSON) to your API
const onChange = (e) => {
// Use the functional update form.
// See https://reactjs.org/docs/hooks-reference.html#functional-updates
setFormData((fd) => ({
...fd,
[e.target.name]: e.target.value,
}));
};
const onSubmit = async (e) => {
e.preventDefault();
const res = await fetch("/api/users", {
method: "POST",
body: JSON.stringify(formData),
headers: { "content-type": "application/json" },
});
if (!res.ok) {
throw new Error(`${res.status}: ${await res.text()}`);
}
const { token } = await res.json();
// do something with token
};
<form className="form" onSubmit={onSubmit}>
You'll probably also want to configure the dev-server proxy in your package.json
file to avoid CORS issues.
"proxy": "http://localhost:5000",
Adjust for the correct port for your Express service.
Server Side
Add the JSON body-parsing middleware before your routes to handle JSON request payloads
app.use(express.json());
CodePudding user response:
You should be able to just send a fetch post request with your formData
:
fetch('[PROTOCOL]://[HOST]/api/users/', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(formData)
})
And you would do this in a function passed into the onSubmit
property of your form:
<form className="form" onSubmit={handleSubmit}>
handleSubmit(event) {
event.preventDefault();
/* fetch post here */
}
Check out the Fetch API and React forms docs for more information.
Also, I would send back you JWT in a cookie, because the alternative of localStorage isn't that great.