Search code examples
node.jsmongodbexpressmongoosemern

MERN - TypeError: Cannot read property 'id' of undefined


I did a lot of research and tried different things but I can seem to resolve certain POST requests.

GET requests and POST requests that add an exercise work but POST requests that delete or update an exercise.

My assumption is that some responses don't get recognized by express in the exercises.js file since it fails whenever Exercise.findById(res.params.id) within the update or delete route is called.

Any help will be much appreciated.

server.js

const express = require('express') // Express web framework
const cors = require('cors') // Cross-origin resource sharing (CORS) -> Connects Express
const mongoose = require('mongoose') // Mongoose will connect us to the mongoDB database

const exercisesRouter = require('./routes/exercises')
const usersRouter = require('./routes/users')

require('dotenv').config() // configure environment variables in .env file

// to create the Express server
const app = express()
const port = process.env.PORT || 5000 // 5000 Port

// Middleware 
app.use(cors()) // CORS middleware
app.use(express.json()) // Express middleware to allow us to parse JSON

// MongoDB Connection process
const uri = process.env.ATLAS_URI // MongoDB database URI connection string form mongoDB Atlas -- ATLAS_URI will be stored in .env file
mongoose.connect(uri, { useNewUrlParser: true, useCreateIndex: true, useUnifiedTopology: true }) // start connection to db
const connection = mongoose.connection
connection.once('open', () => {
    console.log("MongoDB database connection established successfully")
})

// Routing to respective pages
app.use('/exercises', exercisesRouter) // routes to /exercises page
app.use('/users', usersRouter)// routes to /users page

// Start the server
app.listen(port, () => {
    console.log(`Server is running on port: ${port}`)
})

exercises.model.js

const mongoose = require('mongoose')
const Schema = mongoose.Schema

const exerciseSchema = new Schema({
    username: { type: String, required: true },
    description: { type: String, required: true}, 
    duration: { type: Number, required: true},
    date: { type: Date, required: true} 
}, {
    timestamps: true,
})

const Exercise = mongoose.model('Exercise', exerciseSchema)

module.exports = Exercise

exercises.js

const router = require('express').Router() // Creating route for Exercises
let Exercise = require('../models/exercises.model') // Mongoose model

// Handles incoming HTTP GET requests for /exercises URL
router.route('/').get((req, res) => {
    Exercise.find()
        .then(exercises => res.json(exercises))
        .catch(err => res.status(400).json('Error: ' + err))
})

/*** Handles incoming HTTP POST requests ***/

// Create new exercise
router.route('/add').post((req, res) => {
    const username = req.body.username
    const description = req.body.description
    const duration = Number(req.body.duration)
    const date = Date.parse(req.body.date)

    const newExercise = new Exercise({
        username,
        description,
        duration,
        date
    })

    newExercise.save()
    .then(() => res.json('Exercise added !'))
    .catch(err => res.status(400).json('Error = ' + err))
})

// Get exercise by ID
router.route('/:id').get((req, res) => {
    Exercise.findById(req.params.id)
        .then(exercises => res.json(exercises))
        .catch(err => res.status(400).json('Error: ' + err))
})

// Delete exercise
router.route('/:id').delete((res, req) => {
    Exercise.findByIdAndDelete(req.params.id)
    .then(() => res.json('Exercise deleted'))
    .catch(err => res.status(400).json('Error: ' + err))
})

// Update exercise
router.route('/update/:id').post((res, req) => {
    Exercise.findById(req.params.id)
    .then(exercises => {
        exercises.username = req.body.username
        exercises.description = req.body.description
        exercises.duration = Number(req.body.duration)
        exercises.date = Date.parse(req.body.date)

        exercises.save()
            .then(() => res.json('Exercise updated!'))
            .catch(err => res.status(400).json('Error: ' + err))
    })
    .catch(err => res.status(400).json('Error: ' + err))
})


module.exports = router

nodemon server output

[nodemon] starting `node server.js` Server is running on port: 5000 MongoDB database connection established successfully TypeError: Cannot read property 'id' of undefined at C:\Users\sambaetleuk\Projects\mern-fitness-tracker\backend\routes\exercises.js:48:34 at Layer.handle [as handle_request] (C:\Users\sambaetleuk\Projects\mern-fitness-tracker\backend\node_modules\express\lib\router\layer.js:95:5) at next (C:\Users\sambaetleuk\Projects\mern-fitness-tracker\backend\node_modules\express\lib\router\route.js:137:13) at Route.dispatch (C:\Users\sambaetleuk\Projects\mern-fitness-tracker\backend\node_modules\express\lib\router\route.js:112:3) at Layer.handle [as handle_request] (C:\Users\sambaetleuk\Projects\mern-fitness-tracker\backend\node_modules\express\lib\router\layer.js:95:5) at C:\Users\sambaetleuk\Projects\mern-fitness-tracker\backend\node_modules\express\lib\router\index.js:281:22 at param (C:\Users\sambaetleuk\Projects\mern-fitness-tracker\backend\node_modules\express\lib\router\index.js:354:14) at param (C:\Users\sambaetleuk\Projects\mern-fitness-tracker\backend\node_modules\express\lib\router\index.js:365:14) at Function.process_params (C:\Users\sambaetleuk\Projects\mern-fitness-tracker\backend\node_modules\express\lib\router\index.js:410:3) at next (C:\Users\sambaetleuk\Projects\mern-fitness-tracker\backend\node_modules\express\lib\router\index.js:275:10) at Function.handle (C:\Users\sambaetleuk\Projects\mern-fitness-tracker\backend\node_modules\express\lib\router\index.js:174:3) at router (C:\Users\sambaetleuk\Projects\mern-fitness-tracker\backend\node_modules\express\lib\router\index.js:47:12) at Layer.handle [as handle_request] (C:\Users\sambaetleuk\Projects\mern-fitness-tracker\backend\node_modules\express\lib\router\layer.js:95:5) at trim_prefix (C:\Users\sambaetleuk\Projects\mern-fitness-tracker\backend\node_modules\express\lib\router\index.js:317:13) at C:\Users\sambaetleuk\Projects\mern-fitness-tracker\backend\node_modules\express\lib\router\index.js:284:7 at Function.process_params (C:\Users\sambaetleuk\Projects\mern-fitness-tracker\backend\node_modules\express\lib\router\index.js:335:12)


Solution

  • One solution which i can think of it is this -> (req, res) in your callback function since its normally in this sequence.