Nick Kinlen
Nick Kinlen

Reputation: 1406

MERN Stack: POSTing data to database with Express/React

I'm new to the MERN stack and backend programming. I have a React form that I want to submit to an MLab database using Express. I am unable to successfully POST the form data to the database. I'm not sure if I'm taking the correct approach or not. My form is working and I am able to log the fields, I run into problems when trying to do a POST request to submit the form data.

Here is my form:

import React from 'react';
import { Button, Modal, ModalHeader, ModalBody, ModalFooter, Form, FormGroup, Label, Input } from 'reactstrap';

class AddBookModal extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      modal: false,
      bookTitle: '',
      author: '',
      genre: ''
    };

    this.toggle = this.toggle.bind(this);
    this.onSubmit = this.handleSubmit.bind(this);
  }

  toggle() {
    this.setState(prevState => ({
      modal: !prevState.modal
    }));
  }

  handleSubmit = (event) => {
    event.preventDefault();
    const data = this.state;
    //console.log("Data from form :" + data.bookTitle, data.author, data.genre);
  }

  handleInputChange = (event) => {
    event.preventDefault();

    this.setState({
      [event.target.name]:
      event.target.value
    });
  }

  render() {
    const {bookTitle} = this.state;
    const {author} = this.state;
    const {genre} = this.state;
    return (
      <div>
        <Button id="add-book-button" onClick={this.toggle}>Add Book</Button>
        <Modal isOpen={this.state.modal} toggle={this.toggle} className={this.props.className}>
          <ModalHeader toggle={this.toggle}>Add Book</ModalHeader>
          <ModalBody>
            <Form method="POST" action="/profile" id="add-book-form" onSubmit={this.handleSubmit} >
              <FormGroup>
                <Label for="book-title-label">Book Title</Label>
                <Input
                  value={bookTitle}
                  name="bookTitle"
                  onChange={this.handleInputChange}
                  placeholder="Enter name of book" />
              </FormGroup>
              <FormGroup>
                <Label for="book-author-label">Author</Label>
                <Input
                  value={author}
                  name="author"
                  onChange={this.handleInputChange}
                  placeholder="Enter author of book" />
              </FormGroup>
              <FormGroup>
                <Label for="exampleSelect">Genre</Label>
                <Input
                  onChange={this.handleInputChange}
                  value={genre}
                  type="select"
                  name="genre"
                  id="exampleSelect">
                  <option>1</option>
                  <option>2</option>
                  <option>3</option>
                  <option>4</option>
                  <option>5</option>
                </Input>
              </FormGroup>
              <ModalFooter>
                <Button color="primary" type="submit" onClick={this.toggle}>Submit</Button>{' '}
                <Button color="secondary" onClick={this.toggle}>Cancel</Button>
              </ModalFooter>
            </Form>
          </ModalBody>
        </Modal>
      </div>
    );
  }
}

export default AddBookModal;

Here is my Express route:

const router = require('express').Router();
const bodyParser = require('body-parser');

var urlencodedParser = bodyParser.urlencoded({ extended: false });

// localhost:3000/profile

// User Model
const User = require('../../models/user-model');
const Book = require('../../models/book-model');

// Checks if user is not logged in
const authCheck = (req, res, next) => {
    if(!req.user) {
      // If user is not logged in, redirect them to login page
      res.redirect('/auth/login');
    }
    else {
      // If user is logged in call next in router.get
      next();
    }
};

router.get('/', authCheck, (req, res) => {
  res.send('you are logged in, this is your profile : ' + req.user);
});


router.post('/', urlencodedParser, (req, res) => {
  console.log(req.body);

  const newUser = new User({
    name: req.body.name,
    username: req.body.username,
    githubID: req.body.githubID,
    profileUrl: req.body.profileUrl,
    avatar: req.body.avatar,
    books: {
      bookTitle: req.body.bookTitle,
      author: req.body.author,
      genre: req.body.genre
    }
  });

  newUser.save()
    .then(data => {
      res.json(data)
    })
    .catch(err => {
      res.send("Error posting to DB")
    });

});



module.exports = router;

Here is my Express server:

const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const authRoutes = require('./routes/api/auth');
const passportSetup = require('./config/passport-setup');
const cookieSession = require('cookie-session');
const keys = require('./config/keys');
const passport = require('passport');
const profileRoutes = require('./routes/api/profile-routes');
const bookRoutes = require('./routes/api/book-routes');

// Hooks up routes/api/items file
const items = require('./routes/api/items');

const app = express();

// Boderparser Middleware
app.use(bodyParser.json());

// sets up session cookies
app.use(cookieSession({
  // Max age set to 1 day
  maxAge: 24 * 60 * 60 * 1000,
  // Uses cookieKey from keys file to encrypt
  keys: [keys.session.cookieKey]
}));

// initialize passport
app.use(passport.initialize());
app.use(passport.session());

// DB Config
const db = require('./config/keys').mongoURI;

// Connect to mongodb
mongoose
  .connect(db, { useNewUrlParser: true })
  .then(() => console.log('MongoDB Connected'))
  .catch(err => console.log(err));

// Use Routes, sets up routes/api/items to be used
app.use('/api/items', items);

app.use('/book', bookRoutes);

// Use auth.js's routes
app.use('/auth', authRoutes);
// Use profile-routes routes for profile page
app.use('/profile', profileRoutes);

const port = process.env.PORT || 5000;

app.listen(port, () => console.log(`Server started on port ${port}`))

I'm unable to make a POST request and not sure why. The Express route handles some OAuth stuff and displays the logged in user's profile. On that same page I have the form which allows the user to add data and submit it. Is the logic from authCheck interfering with POSTing the form data? The router.post in my Express route does not successfully console.log anything.

I've seen people use Axios in the React form component itself to do a POST request. Is it better to do form POST requests with Axios or should I be handling it in the Express route?

Upvotes: 0

Views: 1727

Answers (1)

Yash Sankhala
Yash Sankhala

Reputation: 41

You should use the axios for making the api call.

In your handleSubmit function you are using "event.preventDefault()" which will prevent the default behavior of the form.

Upvotes: 1

Related Questions