Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript User Authentication With Express and Mongo User Registration Storing Passwords Securely

Dennis Brown
Dennis Brown
28,742 Points

Mongoose ES6/ES2015 Support

Just a forewarning to anyone else, Mongoose does not support ES6/ES2015 syntax at this time (4.7.6).

I was using a fat arrow for my Schema's pre hook anonymous function, and for quite some time I could not figure out why in the world it was not passing the userData down to be hashed. Simply using the ES5 syntax for the anonymous function of course removed this issue, so anyone else that uses ES6 out of habit, be aware.

They are currently discussing adding such support to Mongoose, but since it would require to remove support for Node < 4.x (Before Node/io.js merge), it would be a drastic upgrade/change to the project to support this.

Eli Levit
Eli Levit
4,482 Points

thank you, Dennis!

Henrik Christensen
seal-mask
.a{fill-rule:evenodd;}techdegree
Henrik Christensen
Python Web Development Techdegree Student 38,322 Points

Simply using the ES5 syntax for the anonymous function of course removed this issue, so anyone else that uses ES6 out of habit, be aware. - this just saved my day! :-D

2 Answers

Seth Kroger
Seth Kroger
56,413 Points

This is true of any library/framework that dynamically changes the context of this in handler/hook functions. When you attach the hooks to a Schema you are not inside a Doc or Model. this gets rebound to the Document or Model by Mongoose so it is something useful in context inside the hook. Arrow functions handle this differently than regular functions and do not allow this to be rebound or changed. This is why you need to continue using pre-ES6 syntax here.

Dennis Brown
Dennis Brown
28,742 Points

Oh wow, thank you so much for that! I wasn't aware of that and I will definitely read up on the fat arrow in the spec. I'm guessing this is also why I couldn't find a variable where it was stored otherwise, since the lack of the referenced "this" object was getting lost entirely?

Also, how can you tell when a module is using a dynamic changes like this? I remember hearing about this, but in the context of Webpack module loading (having to import externally), as well as not being able to use the ES6 import/export for these because of how those transpile. I'm guessing this is due to the exact same issue?

Thank you again! My mind is literally blow because of how much all of this is making sense now! :D

You might not be able to use arrow functions, due to the lexical binding of this, but you can use async/await to clean up your code:

UserSchema.pre('save', async function (next) {
  const user = this;

  try {
    const hash = await bcrypt.hash(user.password, 10);
    user.password = hash;
    next();
  } catch (error) {
    return next(error);
  }
});

This is just how arrow functions work - it's a JavaScript thing not a module-specific thing. To quote Valeri Karpov from Mongoose: "That's how arrow functions work. Don't use arrow functions when you're dependant on dynamic function context."

Also if anyone tries this and it doesn't work, you need at least Node v7.6.0 to get async/await.