Home > Net >  How can i send data from a reactjs form to my api and store it in my dabatase?
How can i send data from a reactjs form to my api and store it in my dabatase?

Time:11-23

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.

  • Related