In router/user.js
for routing:
router.post('/register', auth.optional, (req, res, next) => {
const {
body: { user }
} = req
// validation code skipped for brevity
const finalUser = new User(user)
finalUser.setPassword(user.password)
// to save the user in Mongo DB
return finalUser.save().then(() => res.json({ user: finalUser.toAuthJSON() }))
})
Post request sent with a body of:
{
"user":{
"email":"leon@idiot.com",
"password": "123abc"
}
}
In model/User.js
for database schema:
const UserSchema = new Schema({
email: String,
hash: String,
salt: String
})
// Please note: this is a regular/normal function definition
UserSchema.methods.setPassword = function (password) {
// this references the UserSchema created
this.salt = crypto.randomBytes(16).toString('hex')
console.log(`salt: ${this.salt}`)
this.hash = crypto
.pbkdf2Sync(password, this.salt, 10000, 512, 'sha512')
.toString('hex')
console.log(`hash: ${this.hash}`)
}
Everything works fine now. The log output as:
salt: e7e3151de63fc8a90e3621de4db0f72e
hash: 19dd9fdbc78d0baf20513b3086976208ab0f9eee6d68f3c71c72cd123a06459653c24c11148db03772606c40ba4846e2f9c6d4f1014d329f01d22805fc988f6164fc13d4157394b118d921b9cbd742ab510e4d2fd4ed214a0d523262ae2b2f80f6344fbd948e8c858f95ed9706952db90d415312156a994c65c42921afc8c3e5b1b24a923219445eec8ed62de313ab3d78dc93b715689a552b6449870c5bfcc3bec80c4438b1895cab41f92ef681344ac8578de476a82aa798730cf3a6ef86973a4364a8712c6b3d53ce67ffffd7569b9ade5db09ad95490354c6f7194fdd9d8f8a1cb7ccddf59e701198a1beee59a2dd6afb90ae50e26ea480e9a6d607e4b37857a02016ee4d692d468dd9a67499547eb03fc6cfa676686f7990c2251c9516459288c55584138aed56a5df6c4692f7ef6925e8f3d6f6a0c780c4d80580447f2b1258bea799a8c7eb9da878ab70a94c4227ec03d18d56b2722c315d0e2b2681d81d78d4213288f7305cbbfa377c3b2eb75e0f0b093e6067b14adce4a01f0a7bde8515350a1c987739c12574ec4c49008510e2e7e5534f9b76d15b1af68e43ef54e6b8a1bea859aafd23d6b6bc61d5b1965004cd6dd933545cf755f3e6dfc8f230f37a79a8bc006b9b14465b1b08d60cb45ef3b6a1b73f5afac90bdc58d5ec15c7596dc7e8d503f8dfbd6a3289cf997da2031389c7f3d165e34b29178f3daf76d
3
But it does not work with such a definition:
UserSchema.methods.setPassword = password => {
// what this reference is undefined, so are ones below
this.salt = crypto.randomBytes(16).toString('hex')
console.log(`salt: ${this.salt}`)
this.hash = crypto
.pbkdf2Sync(password, this.salt, 10000, 512, 'sha512')
.toString('hex')
console.log(`hash: ${this.hash}`)
}
The error is:
{
"errors": {
"message": "Cannot set property 'salt' of undefined",
"error": {}
}
}
which means what this
referenced is undefined.
What I find online is that fat arrow functions explicitly prevent binding of this
, and it's a problem of scopes, that this
in fat arrow functions has a scope of its immediate object. But I cannot say that I understand it very well.
1. In this case, what is the scope of this
in fat arrow functions?
2. What is the scope, of this
, in normal function definitions?
3. How to access the object, in this case: UserSchema
, properties (forgive me for less proper words) in fat arrow functions as one does in normal function definitions?
These posts are quite helpful:
Are 'Arrow Functions' and 'Functions' equivalent / exchangeable?
How does the “this” keyword work?
But I am still expecting answers to my specific questions in particular cases, before figuring them out.