Happy Patel
Happy Patel

Reputation: 1688

Access has been denied to resolve the property "name" because it is not an "own property" of its parent

I am trying to get the entered details by the user in the form fields so that I can edit and update the selected records. But, when I click the edit button I am getting blank form fields in the form.

router.get('/list', (req, res) => {
    Employee.find((err, docs) => {
        if (!err) {
            res.render("employee/list", {
                list: docs,
            });
        }
        else {
            console.log('Error in retrieving employee list :' + err);
        }
    }); 
})

I am not able to get what went wrong. I have passed the user entered value as req.body. All the operations are working properly but could not update the records as I am not able to get the user id from the form.

<tbody>
    {{#each list}}
    <tr>
        <td>{{this.name}}</td>
        <td>{{this.email}}</td>
        <td>{{this.mobile}}</td>
        <td>{{this.city}}</td>
        <td>
            <a href="/employee/{{this._id}}"><i class="fa fa-pencil fa-lg" aria-hidden="true"></i></a>
            <a href="/employee/delete/{{this._id}}" onclick="return confirm('Are you sure to delete this record ?');"><i class="fa fa-trash fa-lg" aria-hidden="true"></i></a>
        </td>
    </tr>
    {{/each}}
</tbody>

Upvotes: 3

Views: 4980

Answers (3)

KhacVu0505
KhacVu0505

Reputation: 11

You can custom docs before data transmission.

router.get('/list', (req, res) => {
    Employee.find((err, docs) => {
        if (!err) {
            docs= docs.map(item=> item.toObject())
            res.render("employee/list", {
                list: docs,
            });
        }
        else {
            console.log('Error in retrieving employee list :' + err);
        }
    }); 
})

Upvotes: 1

Simon Angatia
Simon Angatia

Reputation: 860

If you are using MySQL, sequelize, use raw query options {raw: true} and if you are using relationships, you can use {nest: true}, eg:

users = await User.findAll({
    where: { username: "SimonAngatia" },
    include: [{ model: Tweet, as: "Tweets" }],
    raw: true,
    nest: true,
  }).catch(errorHandler);

refer here: Sequelize, convert entity to plain object

Upvotes: 0

Happy Patel
Happy Patel

Reputation: 1688

if you are using mongoose and newer versions of express-handlebars, it can be solved by using lean() method after find() like:

router.get('/list', (req, res) => {
Employee.find((err, docs) => {
    if (!err) {
        res.render("employee/list", {
            list: docs,
        });
    }
    else {
        console.log('Error in retrieving employee list :' + err);
    }
})**.lean()**; // It is prevent the warning when trying to display records

})

---------------- Another option you can follow ----------------------------

express-handlebars does not allow you to specify runtime-options to pass to the template function. This package can help you disable prototype checks for your models.

Steps:

1 - Install dependency

npm i @handlebars/allow-prototype-access

2 - Use this snippet as an example to rewrite your express server

const express = require('express')
const path = require('path')
**const Handlebars = require('handlebars')**
**const hbs = require('express-handlebars');**
const bodyParser = require('body-parser');

**const { allowInsecurePrototypeAccess } = require('@handlebars/allow-prototype-access');**
const employeeController = require('./controller/employeeController')

const app = express()
app.use(bodyParser.urlencoded({ extended: true }))
app.use(bodyParser.json())

app.set('views', path.join(__dirname, '/views/'))
app.engine('hbs', hbs({ extname: 'hbs', defaultLayout: 'mainLayout', layoutsDir: __dirname + '/views/layouts/', **handlebars: allowInsecurePrototypeAccess(Handlebars)** }))
app.set('view engine', 'hbs')

app.listen(3000, () => {
    console.log('Server started at port 3000')
})

app.use(employeeController)

3 - Run the server and do your happy dance.

Upvotes: 5

Related Questions