1

For my React/Express app, I've already built my backend API in Express, including a route for posting a blog post (/api/posts). On the front end, I built a form with a method of POST that submits to this route, but when I submit the form I get the error "Cannot POST /api/posts".

app.js (Express)

const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const session = require('express-session');

const app = express();

//Load routes
const photos = require('./routes/photos');
const posts = require('./routes/posts');
const recs = require('./routes/recs');

// DB config
const db = require('./config/database');

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

// Body parser Middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:false}));

// Static folder
app.use(express.static(path.join(__dirname, 'public')));

// Express Session Middleware
app.use(session({
  secret: 'secret',
  resave: true,
  saveUninitialized: true,
  //cookie: {secure: true}

}));

//Router
app.use('/api/photos', photos);
app.use('/api/posts', posts);
app.use('/api/posts', recs);


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

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

Post Route

const express = require('express');
const router = express.Router();
const mongoose = require('mongoose');

// Load Posts model
require('../models/Post');
const Post = mongoose.model('posts')

// Get all posts
router.get('/', (req, res) => {
  Post.find()
    .sort({date:'desc'})
    .then(posts => {
      res.json(posts);
    })
    .catch(err => {
      res.send(err);
    })
});

router.post('/', (req, res) => {
  console.log(req.body); //testing info I receive for now
})

Form

const postForm =
    <div className="form-popup" id="newPost">
      <form action="/api/posts" method="post" className="form-container">
        <h1>New Blog Post</h1>

        <label htmlFor="title"><b>Title</b></label>
        <input type="text" placeholder="Blog Post Title" name="title" required />

        <label htmlFor="location"><b>Location</b></label>
        <input type="text" placeholder="Location" name="location" required />

        <textarea placeholder="Your post here" name="content" required />

        <button type="submit" className="btn">Post</button>
        <button type="submit" className="btn cancel" onClick={this.handleClose}>Close</button>
      </form>
    </div>
7
  • Are you able to access the API via postman? Commented Feb 20, 2019 at 7:10
  • @DanPhilip Nope, I'm getting the same error there. I'm not sure why, as I'm modeling this API on another project I've done. Should I not be sending both get and post requests to the /api/posts? Commented Feb 20, 2019 at 7:24
  • Can you add how you're making the request? Commented Feb 20, 2019 at 7:26
  • @molamk In Postman? I'm sending a POST request to localhost:3000/api/posts with body fields of title: test and location: thailand Commented Feb 20, 2019 at 7:30
  • So that's the problem. You're sending on port 3000, but listening on port 5000 Commented Feb 20, 2019 at 7:32

5 Answers 5

2

From our exchange in the comment, here's the problem

  • The request is sent to port 3000
  • The Node.js server is listening on port 5000.

To solve that you just need to format your request to http://localhost:5000/api/posts

Notes

  • You still need to run React and Node.js on different ports
  • You only need to change the port for your HTTP request
Sign up to request clarification or add additional context in comments.

10 Comments

if this was true the error "Cannot POST /api/posts" would not appear.
How is that? React runs by default on port 3000, which does not support POST requests on a /api/posts route. The message is valid
hm, I think if he got this error it means that he could connect to the server, but the route was not found on server. If there was a connection error like this, the request would just time out without receiving any response.
This is just factually wrong. React catches the request and returns Cannot POST /api/posts. You can try it yourself, [here's a link where you can try that]
@molamk So to ensure I'm understanding, in my form, I would change the action to "/api/posts:5000"? Would this also work in a production environment?
|
1

At the end of Post Route you have to export it.

module.exports = router;

this makes you be able to import it in app.js like you did.

Comments

0

There are two routes with same endpoint.

//Router
app.use('/api/photos', photos);
app.use('/api/posts', posts);
app.use('/api/posts', recs);

I think you wanted a different endpoint for the third route.

//Router
app.use('/api/photos', photos);
app.use('/api/posts', posts);
app.use('/api/recs', recs);

2 Comments

True. But that does not solve the problem, since in the original case the first router on /api/posts is called
Thanks for catching that! It's still throwing the same error when I post though.
0

The action route on the form does not match the post route on the server side.

<form action="/api/posts" method="post" className="form-container">

router.post('/', (req, res) => {

The action route should match the post route for the post action to work.

Comments

0

I was experiencing the same issue and it took me almost half an hour to debug and find the solution.

  • The error:

The error

  • In my case, on the server side, I had used "get" request to declare createPosts instead of "post" request. server side

  • I just changed the "get" request on createPosts to "post", and everything worked fine. I was able to post on the frontend and get a the data. enter image description here

enter image description here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.