Im trying to get a response from my '/users/:uid' endpoint, where it should return data of the specific user if the user is in the database, but it does not work. I get this error: The error
I have a userController file, where i have implemented the function for finding the user based on id in the URL and the userController file is seen in the below:
import { Request, Response } from "express";
import mongoose from "mongoose";
import { schema } from "../models/User";
import { User } from "../models/User";
import {ROUNDS, SALT_LENGTH, KEY_LENGTH, ITERATIONS, DIGEST, pbkdf2, randomBytes} from
"../../authCrypto"
import { join } from 'path'
const X5U = 'http://localhost:3000/auth-rsa256.key.pub';
const PATH_PRIVATE_KEY = join(__dirname, '..', '..', 'auth-rsa.key');
const usersConnection = mongoose.createConnection('mongodb://localhost:27017/users')
const UserModel = usersConnection.model('User', schema)
const listUsers = async (req: Request, res: Response) => {
let result = await UserModel.find({}, ).lean().exec();
res.json(result);
};
const getUser = async (req: Request, res: Response) => {
const {uid} = req.params
let result = await UserModel.find({_id: uid}).lean().exec();
if(!result){
res.json({
"message": "The user is not found"
});
}
res.json(result);
}
module.exports = {
listUsers,
getUser
};
And this is my User model:
import { Schema } from 'mongoose';
export enum Role {
manager = "Manager",
clerk = "Clerk",
guest = "Guest"
}
export interface User{
firstName: string;
middleName: string;
lastName: string;
email: string;
role: Role;
password: string;
salt: string;
}
export const schema = new Schema<User>({
firstName: { type: String, required: true },
middleName: { type: String, required: true },
lastName: { type: String, required: true },
email: { type: String, required: true },
role: { type: String, required: true },
password: { type: String, required: true },
salt: { type: String, required: true},
});
And this is my userRouter:
import { Router } from "express";
const userController = require('../controller/userController')
const userRouter = Router();
userRouter.get('/users', userController.listUsers);
userRouter.get('/users/:uid', userController.getUser);
module.exports = userRouter;
And this is my index file, which is the startfile of the application:
const express = require("express");
const app = express();
const port = 3000;
app.use('/', require("./router/userRouter"));
app.use('/rooms', require('./router/roomRouter'));
app.use('/reservations', require('./router/reservationRouter'));
app.listen(port, () => {
return console.log(`Express is listening at http://localhost:${port}`);
});
CodePudding user response:
The issue:
Based on the error, it looks like the route is passing in "1"
as the :uid
parameter, but the Mongoose .find()
method is trying to coerce it into Mongo's ObjectId
type.
By default, the _id
key in MongoDB is an ObjectId
. ObjectIds are typically a 24 hexadecimal character string (or anything that's 12 bytes), so "1" can't be turned into an ObjectId.
To solve:
- You could set the
_id
column to be of type string or number instead of ObjectId manually. - You could keep the
_ids
as ObjectId type and modify your code to make sure you're passing in valid ids while searching (--adding pre-validation or an error handling wrapper might be good in that case so that the user gets400
s/404s
instead of500
s if something wrong is passed in as a param).
Helpful Resources
Here's a specific rundown on the difference between how the code might look for an _id
that's a string/number vs. an ObjectId
type-- the part about ObjectIds
is at the bottom:
https://masteringjs.io/tutorials/mongoose/find-by-id
Here's some more information general info on MongoDB ObjectIds: https://masteringjs.io/tutorials/mongoose/objectid
Here's some info about the difference between _id
and id
in case that helps with the way you end up wanting to write your queries:
What is the difference between id and _id in mongoose?