-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Instance Methods and Properties returned from Query are undefined #13339
Description
What you are doing?
I am querying for a user using findOne method but the methods and properties of the returned instance are undefined. To be honest, it applies to all type of query that I perform.
I am using Sequelize with TypeScript in defining my model.
interface IUserAuthAttributes {
user_auth_id: number;
username: string;
password: string;
full_name: string;
disable_user: number;
user_level_id: number;
created_modified: string | Date;
}
interface IUserAuthCreationAttributes
extends Optional<IUserAuthAttributes, 'user_auth_id'> { }
export class UserAuth
extends Model<IUserAuthAttributes, IUserAuthCreationAttributes>
implements IUserAuthAttributes {
public user_auth_id!: number;
public username!: string;
public password!: string;
public full_name!: string;
public disable_user: number;
public user_level_id!: number;
public created_modified: string | Date;
public getRole: () => 'meter_reader' | 'evaluator' | null;
}
UserAuth.init({
user_auth_id: {
autoIncrement: true,
type: DataTypes.INTEGER.UNSIGNED,
allowNull: true,
primaryKey: true
},
username: {
type: DataTypes.STRING(20),
allowNull: false,
defaultValue: ""
},
password: {
type: DataTypes.STRING(100),
allowNull: false,
defaultValue: ""
},
full_name: {
type: DataTypes.STRING(100),
allowNull: false,
defaultValue: ""
},
disable_user: {
type: DataTypes.TINYINT,
allowNull: false,
defaultValue: 0
},
user_level_id: {
type: DataTypes.TINYINT,
allowNull: false,
defaultValue: 18
},
created_modified: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP')
}
},
{
sequelize: DBInstance,
tableName: 'user_auth',
timestamps: false
}
);
UserAuth.prototype.getRole = function () {
let role = null;
if (this.user_level_id === 13) {
role = 'meter_reader';
} else if (this.user_level_id === 9) {
role = 'evaluator';
}
return role;
}
What do you expect to happen?
I expect the returned user to be able to execute the getRole instance method and return expected result but fails to execute it and says that TypeError: foundUser.getRole is not a function. Trying to access to other properties like username also fails and I still have to use the getDataValue method like getDataValue('username') to access the username property. I could also use the get method const user = foundUser.get({ plain: true }) or add the { raw: true } on my query to have access on the properties but not on the instance method.
What is actually happening?
This is the code that I'm trying to run.
async login(req: Request, res: Response, next: NextFunction) {
try {
const { username, password } = req.body;
// Check if username exists
const foundUser = await UserAuth.findOne({
where: {
[Op.or]: [
{ user_level_id: 9 },
{ user_level_id: 13 },
],
username: username,
disable_user: 0
},
attributes: {
include: ['user_auth_id', 'username', 'password', 'disable_user']
},
});
if (!foundUser) {
return next(new ErrorHandler(401, 'Incorrect credentials.'));
}
console.log(foundUser.getRole()); // TypeError: foundUser.getRole is not a function
res.status(200).json(foundUser);
} catch (err) {
next(err);
}
}
While inspecting the returned user from the query, using console.log(foundUser), this is what it returns.
UserAuth {
dataValues: {
user_auth_id: 11,
username: 'dhel',
password: '$2a$10$AgiooENdIcVvwK.KQCmAgecT04qgcYbTvzqJ/j0wW/MxvBBVTdV1m',
full_name: 'ADELFA BALATBAT',
disable_user: 0,
user_level_id: 9,
created_modified: 2021-06-21T11:37:29.000Z
},
_previousDataValues: {
user_auth_id: 11,
username: 'dhel',
password: '$2a$10$AgiooENdIcVvwK.KQCmAgecT04qgcYbTvzqJ/j0wW/MxvBBVTdV1m',
full_name: 'ADELFA BALATBAT',
disable_user: 0,
user_level_id: 9,
created_modified: 2021-06-21T11:37:29.000Z
},
_changed: Set(0) {},
_options: {
isNewRecord: false,
_schema: null,
_schemaDelimiter: '',
raw: true,
attributes: [
'user_auth_id',
'username',
'password',
'full_name',
'disable_user',
'user_level_id',
'created_modified',
'user_auth_id',
'username',
'password',
'disable_user'
]
},
isNewRecord: false,
user_auth_id: undefined,
username: undefined,
password: undefined,
full_name: undefined,
disable_user: undefined,
user_level_id: undefined,
created_modified: undefined,
toUserJSON: undefined,
getRole: undefined
}
As you can see from the returned User from above, the instance methods getRole is undefined as well as properties outside dataValues.
Which dialect you are using ?
I am using mysql
Which sequelize version you are using?
I am using using sequlize: 6.6.2 mysql2: 2.2.5 typescript:.4.2.4
More info
I am using ts-node: 9.1.1 , tsconfig-paths:3.9.0 in order to compile and resolve path aliases on my typescript code.
and start my server with this script "start": "nodemon --exec ts-node --files -r tsconfig-paths/register src/index.ts"
My tsconfig.json
{
"compilerOptions": {
"target": "esnext",
"lib": [ "esnext", "esnext.asynciterable" ],
"baseUrl": ".",
"paths": {
"@/*": [ "./src/*" ]
},
"typeRoots": [ "./node_modules/@types", "./src/types" ],
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node",
"module": "commonjs",
"pretty": true,
"sourceMap": true,
"outDir": "./build",
"allowJs": true,
"noEmit": false,
"skipLibCheck": true,
"esModuleInterop": true,
"resolveJsonModule": true
},
"include": [ "./src/**/*", ".sequelizerc", ".env" ],
"exclude": [ "node_modules" ],
}
It would be really helpful if you can give me an insight as to why this is happening.