0

I need help using handlebars. I'm trying to insert an username into my index.hbs using {{user.username}}. The thing is that it shows me this:

Handlebars: Access has been denied to resolve the property "username" because it is not an "own property" of its parent.

const express = require('express');
const path = require('path');
const exphbs = require('express-handlebars');
const methodOverride = require('method-override');
const session = require('express-session');
const flash = require('connect-flash');
const passport = require('passport');

const app = express();
require('./database');
require('./config/passport');

//Configuracion
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));

app.engine('.hbs', exphbs({
    defaultLayout: 'main',
    layoutsDir: path.join(app.get('views'), 'layouts'),
    partialsDir: path.join(app.get('views'), 'partials'),
    extname: '.hbs'    
}));

app.set('view engine', '.hbs');

//Middlewares
app.use(express.urlencoded({extended: false}));
app.use(methodOverride('_method'));
app.use(session({
    secret: 'clavesecreta',
    resave: true,
    saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());

app.use(flash());

//Variables
app.use((req, res, next) => {
    res.locals.success_msg = req.flash('success_msg');
    res.locals.error_msg = req.flash('error_msg');
    res.locals.error = req.flash('error');
    res.locals.user = req.user || null;
    next();
});

//Routes
app.use(require('./routes/index'));
app.use(require('./routes/videos'));
app.use(require('./routes/users'));

//Archivos estaticos
app.use(express.static(path.join(__dirname, 'public')));

//Iniciar server
app.listen(app.get('port'), () => {
    console.log('El servidor esta escuchando en el puerto', app.get('port'))
});

Here is where I get the user.username. I also insert my user.js model:

const mongoose = require('mongoose');
const { Schema } = mongoose;
const bcrypt = require('bcryptjs');

const UserSchema = new Schema({
    username: { type: String, required: true},
    email: { type: String, required: true},
    password: {type: String, required: true},
    date: {type: Date, default: Date.now}
});

UserSchema.methods.encryptPassword = async (password) => {
    const salt = await bcrypt.genSalt(10);
    const hash = bcrypt.hash(password, salt);
    return hash;
};

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

module.exports = mongoose.model('User', UserSchema)
zhulien
  • 5,145
  • 3
  • 22
  • 36
davidf214
  • 3
  • 2
  • Presumably `req.user` is not a plain object, but without a [mre] it's hard to say where it came from. – jonrsharpe Mar 22 '21 at 22:23
  • I just updated all my index.js, sorry about that but im new at this. In my hbs I only insert {{user.username}} – davidf214 Mar 22 '21 at 22:59
  • Does this answer your question? [Handlebars: Access has been denied to resolve the property "from" because it is not an "own property" of its parent](https://stackoverflow.com/questions/59690923/handlebars-access-has-been-denied-to-resolve-the-property-from-because-it-is) – jonrsharpe Mar 23 '21 at 07:40
  • Well, I looked into this before and I solved a lot of issues on my code. The problem is that I cant place a .lean() in res.locals.user = req.user || null; so I dont know what to do – davidf214 Mar 23 '21 at 16:21

1 Answers1

1

I solved the problem by removing res.locals.user in app.js middleware, and moved it to the userAuthenticated function. And also add .toJSON() after req.user to serialized it.

Here's example code from my userAuthenticated function:

module.exports.userAuthenticated = function (req, res, next) {
    if (req.isAuthenticated()) {
        res.locals.user = req.user.toJSON() || null;
        return next();
    }
    res.redirect('/');
},
Gridnity
  • 26
  • 2