sequelize-typescript
sequelize-typescript copied to clipboard
@BeforeUpdate and @BeforeCreate user instance to be modified is undefined
Issue
Hello everyone, I have this issue please take a look and suggest anythig cause I'm stock here, when I call @BeforeUpdate and @BeforeCreate hooks in the model, they're triggered, the coming new instance is valid but their attributtes are undefined.
Versions
- sequelize: 6.20.0
- sequelize-typescript: 2.1.3
- typescript: 4.6.4
Issue type
- [ x] bug report
- [ ] feature request
Actual behavior
In the model when I create User definition, I am trying to catch beforeCreate and BeforeUpdate behavior in order to hash the password, so I use @BeforeUpdate and @BeforeCreate hooks to do that, they are triggered as expected, but nothig happened, then I put some console.logs there and I notice that they are triggered as expected, then I consoled the whole instance Object:
@BeforeUpdate
static hashPasswordBeforeUpdate(user: User, options: any) {
let salt = bcrypt.genSaltSync(12);
console.log("Password2:"+bcrypt.hashSync("holaPajuo", salt));
console.log("Entered HookHashUpdate:"+JSON.stringify(user));
console.log("PassData: "+JSON.stringify(user.password));
if (user.password) {
user.password = bcrypt.hashSync(user.password, salt);
}
}
Result:
Password2:$2a$12$LuyXzkEyQZvJNTh7fiLR0u4IxnmyJmJX4n4N3dPh9C.cjz7YMXx.2
Entered HookHashUpdate:{"id":25,"first_name":"nombre prueba2","last_name":"apellido prueba2","username":"prueba2","password":"123456","phone":null,"cell_phone":"33234343","email":"[email protected]","address":"prueba2","zip_code":"prueba2","id_location":1,"id_company":1,"status":true}
PassData: undefined
As you can notice, they are triggered, it can hash the password with an alternative string, I logged the whole incoming instance and it is there, but when I console log any of the attributes in order to modify it, like the password it says that it is undefined....crazy isn't it?
It is driving me crazy.....
Expected behavior
I expect to call user.password and modify it with an hashed string based on its actual value
Steps to reproduce
just update or create and item and watch the console
Related code
files. user.model.ts
import {
Table,
Model,
Column,
DataType,
BeforeCreate,
BeforeUpdate,
Sequelize
} from "sequelize-typescript";
import bcrypt from 'bcryptjs';
/* TABLE USER */
@Table({
timestamps: false,
freezeTableName: true,
tableName: 'user'
})
class User extends Model {
@Column({
type: DataType.STRING(100),
allowNull: false
})
first_name!: string;
@Column({
type: DataType.STRING(100),
allowNull: false
})
last_name!: string;
@Column({
type: DataType.STRING(40),
allowNull: false
})
username!: string;
@Column({
type: DataType.STRING(80),
allowNull: false
})
password!: string;
@Column({
type: DataType.STRING(50),
allowNull: true
})
phone!: string;
@Column({
type: DataType.STRING(50),
allowNull: false
})
cell_phone!: string;
@Column({
type: DataType.STRING(60),
allowNull: false,
validate: { isEmail: true }
})
email!: string;
@Column({
type: DataType.TEXT,
allowNull: true
})
address!: string;
@Column({
type: DataType.STRING(20),
allowNull: true
})
zip_code!: string;
@Column({
type: DataType.INTEGER,
allowNull: true
})
id_location!: number;
@Column({
type: DataType.INTEGER,
allowNull: true
})
id_company!: number;
@Column({
type: DataType.BOOLEAN,
allowNull: false,
defaultValue: true
})
status!: boolean;
@BeforeCreate
static BeforeCreateHook(user: User){
let salt = bcrypt.genSaltSync(12);
console.log("Password2:"+bcrypt.hashSync("holaPajuo", salt));
console.log("Entered HookHashCreate: "+JSON.stringify(user));
//console.log("PassData: "+JSON.stringify(user));
if (user.password) {
console.log("Password2:"+bcrypt.hashSync(user.password, salt));
user.password = bcrypt.hashSync(user.password, salt);
}
}
@BeforeUpdate
static hashPasswordBeforeUpdate(user: User, options: any) {
let salt = bcrypt.genSaltSync(12);
console.log("Password2:"+bcrypt.hashSync("holaPajuo", salt));
console.log("Entered HookHashUpdate:"+JSON.stringify(user));
console.log("PassData: "+JSON.stringify(user.password));
if (user.password) {
user.password = bcrypt.hashSync(user.password, salt);
}
}
}
export default User;
my user.datasource.ts
user.datasource.ts
public async userUpdate(data: User, id: number): Promise<any> { //TODO: try to don't use any
try{
return await UserModel.update(data, { where: {id : id}, individualHooks: true });
}catch(err) {
throw err;
}
}
public async userSave(data: User): Promise<User> {
const userToSave = new UserModel({
first_name: data.first_name,
last_name: data.last_name,
username: data.username,
password: data.password,
email: data.email,
cell_phone: data.cell_phone,
phone: data.phone,
address: data.address,
zip_code: data.zip_code,
id_location: data.id_location,
id_company: data.id_company,
status: data.status
});
try{
return await userToSave.save();
}catch(err) {
throw err;
}
}
}
tsconfig.json
{
"compilerOptions": {
"sourceMap": true,
"outDir": "dist",
"strict": true,
"lib": [
"esnext"
],
"esModuleInterop": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"target": "esnext",
"moduleResolution": "Node",
"strictNullChecks":false
}
}
database.connection.ts
import { Sequelize } from "sequelize-typescript";
import { User } from "../models";
import dotenv from "dotenv";
dotenv.config();
const connection = new Sequelize(
process.env.DB_NAME as string,
process.env.DB_USER as string,
process.env.DB_PASSWORD as string
,
{
host: process.env.DB_HOST,
dialect: 'mysql',
models: [__dirname + '../models']
});
connection.addModels([ User ]);
connection
.authenticate()
.then(() => {
console.log('Connection has been established successfully.');
})
.catch(err => {
console.error('Unable to connect to the database:', err);
});
export default connection;
I hope you can notice what is happening. Thanks in Advance