Prathamesh Patil
Prathamesh Patil

Reputation: 11

Cannot read properties of undefined (reading '_id') and Cast to ObjectId failed for value for express router

So I am having this two error in my terminal(postman):

This one for my authUser function in authController.js:

{
    "message": "Cast to ObjectId failed for value \"{ email: '[email protected]' }\" (type Object) at path \"_id\" for model \"User\"",
    "stack": "CastError: Cast to ObjectId failed for value \"{ email: '[email protected]' }\" (type Object) at path \"_id\" for model \"User\"\n    at SchemaObjectId.cast (D:\\PRATHAMESH\\My_React\\inotebook\\backend\\node_modules\\mongoose\\lib\\schema\\objectId.js:250:11)\n    at SchemaType.applySetters (D:\\PRATHAMESH\\My_React\\inotebook\\backend\\node_modules\\mongoose\\lib\\schemaType.js:1255:12)\n    at SchemaType.castForQuery (D:\\PRATHAMESH\\My_React\\inotebook\\backend\\node_modules\\mongoose\\lib\\schemaType.js:1673:17)\n    at cast (D:\\PRATHAMESH\\My_React\\inotebook\\backend\\node_modules\\mongoose\\lib\\cast.js:319:34)\n    at Query.cast (D:\\PRATHAMESH\\My_React\\inotebook\\backend\\node_modules\\mongoose\\lib\\query.js:4889:12)\n    at Query._castConditions (D:\\PRATHAMESH\\My_React\\inotebook\\backend\\node_modules\\mongoose\\lib\\query.js:2306:10)\n    at model.Query._findOne (D:\\PRATHAMESH\\My_React\\inotebook\\backend\\node_modules\\mongoose\\lib\\query.js:2630:8)\n    at model.Query.exec (D:\\PRATHAMESH\\My_React\\inotebook\\backend\\node_modules\\mongoose\\lib\\query.js:4438:80)\n    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n    at async D:\\PRATHAMESH\\My_React\\inotebook\\backend\\controllers\\authController.js:43:18"
}

and This one for my getUserProfile function in authController.js:

{
    "message": "Cannot read properties of undefined (reading '_id')",
    "stack": "TypeError: Cannot read properties of undefined (reading '_id')\n    at D:\\PRATHAMESH\\My_React\\inotebook\\backend\\controllers\\authController.js:60:47\n    at asyncUtilWrap (D:\\PRATHAMESH\\My_React\\inotebook\\backend\\node_modules\\express-async-handler\\index.js:3:20)\n    at Layer.handle [as handle_request] (D:\\PRATHAMESH\\My_React\\inotebook\\backend\\node_modules\\express\\lib\\router\\layer.js:95:5)\n    at next (D:\\PRATHAMESH\\My_React\\inotebook\\backend\\node_modules\\express\\lib\\router\\route.js:149:13)\n    at Route.dispatch (D:\\PRATHAMESH\\My_React\\inotebook\\backend\\node_modules\\express\\lib\\router\\route.js:119:3)\n    at Layer.handle [as handle_request] (D:\\PRATHAMESH\\My_React\\inotebook\\backend\\node_modules\\express\\lib\\router\\layer.js:95:5)\n    at D:\\PRATHAMESH\\My_React\\inotebook\\backend\\node_modules\\express\\lib\\router\\index.js:284:15\n    at Function.process_params (D:\\PRATHAMESH\\My_React\\inotebook\\backend\\node_modules\\express\\lib\\router\\index.js:346:12)\n    at next (D:\\PRATHAMESH\\My_React\\inotebook\\backend\\node_modules\\express\\lib\\router\\index.js:280:10)\n    at Function.handle (D:\\PRATHAMESH\\My_React\\inotebook\\backend\\node_modules\\express\\lib\\router\\index.js:175:3)"
}

But, registerUser runs quite well. Pls help. Here are my files:

Here controllers/authController.js:



const User = require('../models/User');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcrypt');
const asyncHandler = require('express-async-handler');

const generateToken = (_id) => {
    return jwt.sign({ _id }, process.env.JWT_SECRET, {
        expiresIn: '30d',
    });
};

//Register User
const registerUser = asyncHandler(async (req, res) => {
    const { name, email, password } = req.body;
    const userExists = await User.findOne({ email });
    if(userExists){
        res.status(400);
        throw new Error('User already exits');
    }

    const user = await User.create({
        name,
        email,
        password
    });
    if(user){
        res.status(201).json({
            _id: user._id,
            name: user.name,
            email: user.email,
            token: generateToken(user._id),
        });
    }else{
        res.status(400);
        throw new Error('Invalid User Data');
    }
});

//Authentication user & get token
const authUser = asyncHandler(async (req, res) => {
    const { email, password } = req.body;

    const user = await User.findById({ email });

    if(user && (await user.matchPassword(password))){
        res.json({
            _id: user._id,
            name: user.name,
            email: user.email,
            token: generateToken(user._id),
        });
    }else{
        res.status(401);
        throw new Error('Invalid email or password');
    }
});

//Get User's Profile
const getUserProfile = asyncHandler(async (req, res) => {
    const user = await User.findById(req.user._id);
    if(user){
        res.status(201).json({
            _id: user._id,
            name: user.name,
            email: user.email,
            token: generateToken(user._id),
        });
    }else{
        res.status(404);
        throw new Error('User not found');
    }
});

module.exports = { registerUser, authUser, getUserProfile };

middleware/authMiddleware.js:

const jwt = require('jsonwebtoken');
const asyncHandler = require('express-async-handler');
const User = require('../models/User');

const protect = asyncHandler(async (req, res, next) => {
    let token;

    if(req.headers.authorization && req.headers.authorization.startsWith('Bearer')){
        try{
            token = req.headers.authorization.split('')[1];
            const decoded = jwt.verify(token, process.env.JWT_SECRET);
            req.user = await User.findBy(decoded.id).select('-password');
            next();
        } catch(err){
            console.log(err);
            res.status(401);
            throw new Error('Not authorized, token failed');
        }
    }

    if(!token){
        res.status(401);
        throw new Error('Not authorized, no token');
    }
});

module.exports = { protect };

middleware/errorMiddleware.js:

const notFound = (req, res, next) => {
    const error = new Error(`Not Found - ${req.orginalUrl}`);
    res.status(404);
    next(error);
};

const errorHandler = (err, req, res, next) => {
    const statusCode = res.statusCode === 200 ? 500 : res.statusCode;
    res.status(statusCode);
    res.json({
        message : err.message,
        stack : process.env.NODE_ENV === 'production' ? null : err.stack,
    });
};

module.exports = { notFound, errorHandler };

models/User.js:

const mongoose = require('mongoose');
const bcrypt = require('bcrypt');

// define the User model schema
const UserSchema = new mongoose.Schema({
  name:{
    type: String,
    required: true
  },
  email: {
    type: String,
    index: { unique: true },
    required: true
  },
  password: {
    type: String,
    required: true
  }
});

UserSchema.pre('save', async function (next) {
  if(!this.isModified('password')){
    next();
  }
  const salt = await bcrypt.genSalt(10);
  this.password = await bcrypt.hash(this.password, salt);
})

UserSchema.methods.matchPassword = async function (enteredPassword) {
  return await bcrypt.compare(enteredPassword, this.password);
}

const User = mongoose.model('User', UserSchema);
module.exports = User;

models/Notes.js:

const mongoose = require('mongoose');

const NotesSchema = new mongoose.Schema({
  title:{
    type: String,
    required: true
  },
  content: {
    type: String,
    required: true
  }
});

const Notes = mongoose.model('Notes', UserSchema);
module.exports = Notes;

routes/authRoutes.js:

const express = require('express');
const { registerUser, authUser, getUserProfile } = require('../controllers/authController')
const{ protect } = require('../middleware/authMiddleware');

const router = express.Router();

router.post('/register', registerUser);
router.post('/login', authUser);
router.get('/profile', getUserProfile);

module.exports = router;

db.js:

const mongoose = require('mongoose');

const mongoDBURL = "mongodb://127.0.0.1:27017/iNotebookDatabase?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+2.3.4";
const connectToMongo = mongoose.connect(mongoDBURL)
    .then(() => console.log('Connected to MongoDB'))
    .catch(err => console.error('MongoDB connection error:', err));

module.exports = connectToMongo;

index.js:

const connectToMongo = require('./db');
const express = require('express');
const cors = require('cors');
const authRoutes = require('./routes/authRoutes')
const { notFound, errorHandler } = require('./middleware/errorMiddleware');
const dotenv = require('dotenv'); 
dotenv.config();

const app = express();
const PORT = 5000;
app.use(express.json());


app.use('/api/auth', authRoutes);

app.use(notFound);
app.use(errorHandler);

connectToMongo
      .then(() => {
            app.listen(PORT, () => {
                  console.log(`Server is running on port http://localhost:${PORT}`);
            });
      })
      .catch(err => console.log(err));

.env:

JWT_SECRET="Chaleya";
NODE_ENV="production";

Upvotes: 0

Views: 20

Answers (0)

Related Questions