0

I'm havig trouble understanding how to access the properties of a global variable that is set in the middleware of my application

// app.js
app.use(function (req, res, next) {
  res.locals.user = req.user || null;
  next();
});

I would have thought I could access the req.user.username in my template (using handlebars), but for some reason it is forcing me to iterate over this object.

A consle.log(req.user) shows:

  _id: 5f01f9a861f5b33b42a9e,
  username: 'onetap',
  email: 'test@gmail.com',
  password: '$2b$10$VLBS8ZwPKiaXasdfsiiwfg.wyJ1J5CwTKLjS5zXwAsvukHpNmk0HG2',
  createdAt: 2020-07-05T16:02:48.081Z,
  __v: 0
}

And in my template I have to use an each loop and can't access the properties directly. the req.user is not an array either.

{{user.username}}//undefined

{{#each user}}
{{username}}  //onetap
{{/each}}

passport.js file

const LocalStrategy = require("passport-local").Strategy;
const bcrypt = require("bcrypt");
const mongoose = require("mongoose");

// Load User Model
const User = require("../models/User");

module.exports = function (passport) {
  passport.use(
    new LocalStrategy({ username: "username" }, (username, password, done) => {
      //   Match User
      User.findOne({
        username: username,
      }).then((user) => {
        if (!user) {
          return done(null, false, { message: "Invalid Username" });
        }
        console.log("Checking password");
        // Match password
        bcrypt.compare(password, user.password, (err, isMatch) => {
          if (err) throw err;
          if (isMatch) {
            return done(null, user);
          } else {
            return done(null, false, { message: "Password incorrect" });
          }
        });
      });
    })
  );

  passport.serializeUser(function (user, done) {
    done(null, user.id);
  });

  passport.deserializeUser(function (id, done) {
    User.findById(id, function (err, user) {
      done(err, user);
    });
  });
};

I was able to fix this by chaning deserialize to:

  passport.deserializeUser(function (id, done) {
    User.findById(id)
      .lean()
      .exec(function (err, user) {
        done(err, user);
      });
  });
onetap
  • 165
  • 1
  • 1
  • 8
  • https://stackoverflow.com/questions/9058774/handlebars-mustache-is-there-a-built-in-way-to-loop-through-the-properties-of – Shivaji Mutkule Jul 08 '20 at 14:08
  • 1
    Can you show us how you actually pass the `user`-object to the template? `res.render(...)`? – eol Jul 08 '20 at 14:09
  • I'm not passing it to the template, it was set globally. The main question I have is why do I need to iterate over this? – onetap Jul 08 '20 at 14:17
  • 2
    I assume you are using mongoose ?! mongoose does not return a plain js object until you use `.lean()` in your query. if you use "lean" it should work – Marc Jul 08 '20 at 14:24
  • @marc Yes, using mongoose. I read that it returns a mongoose document. I'm still unsure where I would use the .lean() – onetap Jul 08 '20 at 14:28
  • @onetap where does `req.user` come from ? where is the data patched to the request object? – Marc Jul 08 '20 at 14:29
  • Is ```req.user``` an array of objects ? – Vipulw Jul 08 '20 at 14:30
  • It is not an array. This is my first project so not entirely sure. I'm using passport-local so I think it may be when I deserialize the user. I will update the question to include my passport config file – onetap Jul 08 '20 at 14:33

0 Answers0