Pre hooks
Pre hooks
Add methods to execute before "save", "delete", "findOne" or your customMethod. The middleware that you declare receives the original argument(s) passed to the method. You can modify them in your resolve passing an object with an __override property containing the new parameter(s) for the target method (be careful though... with great power comes great responsibility!). See example below. If you reject the Promise in a "pre" middleware, the target function is not executed.
Example
Hook to hash a user's password before saving it into the Datastore.
const { instances } = require('gstore-node');
const bscrypt = require('bcrypt-nodejs');
const gstore = instances.get('default');
const userSchema = new gstore.Schema({
user: { type: String },
email: { type: String, validate: 'isEmail' },
password: { type: String, excludeFromIndexes: true }
});
// Hash password middleware
function hashPassword() {
// scope *this* is the entity instance
const _this = this;
const password = this.password;
if (!password) {
// nothing to hash... exit
return Promise.resolve();
}
return new Promise((resolve, reject) => {
bcrypt.genSalt(5, function onSalt(err, salt) {
if (err) {
return reject(err);
};
bcrypt.hash(password, salt, null, function onHash(err, hash) {
if (err) {
// reject will *not* save the entity
return reject(err);
};
_this.password = hash;
// resolve to go to next middleware or target method
return resolve();
});
});
});
}
// add the "pre" middleware to the save method
userSchema.pre('save', hashPassword);
...
// Then when you create a new user and save it (or when updating it)
// the password will automatically be hashed
const User = require('./user.model');
const user = new User({ username: 'john', password: 'mypassword' });
user.save()
.then((response) => {
const entity = response[0];
console.log(entity.password);
// $7b$01$GE/7OqVnMyThnaGC3QfEwuQ1imjifli3MvjcP7UGFHAe2AuGzne5.
});Note The pre('delete') hook has its scope set on the entity to be deleted. Except when an Array of ids to delete is passed.
You can also pass an Array of middlewares to execute
Dataloader instance
In case you provided a Dataloader instance to a Model.update() call, it will be added to the entity being saved. This means that it is accessible from inside your "pre" save hooks.
Override parameters
In the rare cases (maybe during a migration of data) where you'd need to override the parameters in a "pre" hook, you can resolve your middleware with an object containing an __overrideproperty.
Last updated
Was this helpful?