I am a beginner and got stuck in this problem. I am building an app where I want the admin to update any user who are displayed in the admin panel by clicking on the update button at the bottom of the user profile. Admin can change the name , gender etc by just replacing the values on the displayed user container. I am unable to update the user from the Admin pannel and when I am trying to update the user then I am getting the following error:
Cast to ObjectId failed for value ':id' (type string) at path '_id' for model 'User'
Below is my index.js file
import 'core-js'
import 'regenerator-runtime/runtime'
import { login, logout } from './login'
import { updateSettings, createUser, updateUser } from './settings'
const updateUserForm = document.querySelector('#update-user')
if (updateUserForm) updateUserForm.addEventListener('click', e => {
e.preventDefault()
const form = new FormData()
form.append('name', document.getElementById('name').value)
form.append('email', document.getElementById('email').value)
form.append('gender', document.getElementById('gender').value)
form.append('number', document.getElementById('number').value)
updateUser(form)
})
Below id my settings.js file
import axios from 'axios'
import { showAlert } from './alerts'
export const updateUser = async(data) => {
try{
const res = await axios({
method: 'PATCH',
url: (process.env.NODE_ENV === 'production') ? 'api/v1/users/:id' : 'http://127.0.0.1:5500/api/v1/users/:id',
data
})
if (res.data.status == 'success') {
showAlert('success', 'User updated successsfully!')
}
location.reload(true)
}
catch(err) {
showAlert('error', err.response.data.message)
}
}
Below is userRoutes.js file
const express = require('express')
const userController = require('./../controllers/userController')
const authController = require('./../controllers/authController')
const router = express.Router()
router.use(authController.protect)
router.use(authController.restrictTo('librarian'))
router.route('/:id').get(userController.getUser).patch(userController.updateUser).delete(userController.deleteUser)
module.exports = router
Below is userController.js
const factory = require('../controllers/handlerFactory')
exports.getUser = factory.getOne(User)
exports.updateUser = factory.updateOne(User)
exports.deleteUser = factory.deleteOne(User)
Below is handlerFactory.js
const {Model} = require('mongoose')
const catchAsync = require('../utils/catchAsync')
const AppError = require('../utils/appError')
exports.updateOne = Model => catchAsync(async(req, res, next) => {
const doc = await Model.findByIdAndUpdate(req.params.id, req.body, {
new: true,
runValidators: true
})
if (!doc) {
return next(new AppError('No document found with that ID', 404))
}
res.status(200).json({
status: 'success',
data: {
data: doc
}
})
})
Below is viewRoutes.js
const express = require('express')
const authController = require('../controllers/authController')
const viewController = require('../controllers/viewController')
const router = express.Router()
router.get('/students', authController.protect, viewController.getStudents)
module.exports = router
Below is viewController.js
const User = require('../models/userModel')
const catchAsync = require('../utils/catchAsync')
exports.getStudents = catchAsync(async(req, res) => {
const students = await User.find()
res.status(200).render('students', {
title: 'Students',
students
})
})
Below is students.pug
extends account
block user-account
#user-account-content
#display-user-containers
each student in students
if (student.role === 'student')
form#get-user-form
#user-container
#user-container-header
img#user-container-photo(src=`/img/users/${student.photo}`, alt=`${student.name} image`)
input#name(type="text", value=`${student.name}`, name="name")
#user-container-main
#user-container-main-heading
| Details
label(for="email")
| Email Address
input#email.user-container-input(type="email", value=`${student.email}`, name="email")
label(for="gender")
| Gender
input#gender.user-container-input(type="text", value=`${student.gender}`, name="gender")
label(for="number")
| Phone No.
input#number.user-container-input(type="number", value=`${student.number}`, name="number")
#user-container-footer
button#update-user.upd-dlt-view-btn
| Update
button#delete-user.upd-dlt-view-btn
| Delete
button#view-books-issued.upd-dlt-view-btn
| Issues
It will be much easy to help if you can narrow down an exact lines where this error occur with exact error message you see in console. I think it's coming from here
Check if req.params.id is exist and id is mongoose.Types.ObjectId.