I am building an app where I want the admin to update any user who are displayed in the admin panel

61 Views Asked by At

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

1

There are 1 best solutions below

0
dimonD On

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

exports.updateOne = Model => catchAsync(async(req, res, next) =>  {
const doc = await Model.findByIdAndUpdate(req.params.id, req.body, {

Check if req.params.id is exist and id is mongoose.Types.ObjectId.