Alexandru Popovici
Alexandru Popovici

Reputation: 143

express js route never hits /:id

I have a situation when I can not access a express js route which points to "/:id". It always hits "/" and I do not understand why?

The code in my controller is as follows:

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

router.use(bodyParser.urlencoded({
    extended: true
}));
router.use(bodyParser.json());

var Reservation = require('./Reservation');

// GET all reservations
router.get('/', function (req, res) {
    Reservation.find({}).populate('client').exec(function (err, reservation) {
        if (err) return res.status(500).send("Issues retrieving all reservations.");
        res.status(200).send(reservation);
    });
});

// GET only one reservation based on its ID
router.get('/:id', function (req, res) {
    Reservation.findById(req.params.id).populate('client').exec(function (err, reservation) {
        if (err) return res.status(500).send("Issues finding the reservation.");
        if (!reservation) return res.status(404).send("Reservation not found.");
        res.status(200).send(reservation);
    });
});

In my app.js file, I mount the controller onto the route as follows:

var ReservationController = require('./reservations/ReservationController'); 
app.use('/api/reservations', ReservationController);

This is how I'm trying to retrieve the reservation by id using Axios:

axios
  .get('http://localhost:3000/api/reservations/', {
      params: {
        id: '5a6dd589a90c1e83d3c3ebb8'
      }
  })
  .then(response => {
    // handle response
  })
  .catch(e => {
    // handle errors
  })

Tried using Postman with the same results, I'm always getting "/" instead of "/:id".

Upvotes: 1

Views: 604

Answers (2)

David Vicente
David Vicente

Reputation: 3111

The problem probably is that you declared first '/' path than '/:id'.

So, the middleware try to match every entry request in the same order you declared the paths. The request you send with the id is probably being treated by the first method because it matchs the path. You always have to declare more specific paths first, and then the generic ones. Other case, specific ones are not going to work ever.

Change the order you delcared the paths into the middleware and tell me if it worked.

Upvotes: 0

Jeremy Thille
Jeremy Thille

Reputation: 26360

GET /api/reservations doesn't match /:id. /:id implies that the route is called by passing the id as a path parameter.

You can invoke /:id by using :

axios.get('/5a6dd589a90c1e83d3c3ebb8')

This matches /:id. And then you'll get req.params.id=="5a6dd589a90c1e83d3c3ebb8" in your route handler function.

If you call /api/reservations, it would match router.get('/:param1/:param2') and then you'd get req.params.param1=="api" and req.params.param2=="reservations".

Edit (by @ChiragRavindra)

If you intended to call /api/reservations/5a6dd589a90c1e83d3c3ebb8, you would need need to change your matching expression to: router.get('/api/reservations/:id', function (req, res) {...} (Assuming you are not mounting your controller on /api/reservations in the first place). You can then invoke it like:

axios.get('/api/reservations/5a6dd589a90c1e83d3c3ebb8')

If you want to keep the invocation the same as you have posted in the question, you will have to change the HTTP method to PUT or POST from GET

router.post('/api/reservations', function (req, res) {
    //req.body.params.id === '5a6dd589a90c1e83d3c3ebb8'
});



axios
.post('/api/reservations/', {
    params: {
        id: '5a6dd589a90c1e83d3c3ebb8'
    }
})
.then(response => {
    // handle response
})
.catch(e => {
    // handle errors
})

Upvotes: 3

Related Questions