'How to declare an instance of a class inside a function
This is my user.js function. How do I create an instance of it in another file? I understand that this structure is a function that contains a class that contains functions inside it.
user.js
'use strict';
const {Sequelize} = require('sequelize');
const {
Model
} = require('sequelize');
//This is a function that contains a class that contains functions
module.exports = (sequelize, DataTypes) => {
class User extends Model {
static init(sequelize) {
super.init(
{
name: Sequelize.STRING,
},
{
sequelize,
});
this.addHook('beforeSave', async (user) => {
return user.id = uuid();
});
return this;
}
static associate(models) {
// define association here
User.hasMany(UserRole,
{
foreignKey: {
field:'UserId',
allowNull: false,
},
});
}
}
User.init({
Id: DataTypes.UUID,
Name: DataTypes.STRING,
UserName: DataTypes.STRING,
Email: DataTypes.STRING,
Password: DataTypes.STRING,
PhoneNumber: DataTypes.STRING,
MobileNumber: DataTypes.STRING,
DateOfBirth: DataTypes.DATE,
LockoutEnabled: DataTypes.BOOLEAN,
LockoutEnd: DataTypes.DATE
}, {
sequelize,
modelName: 'User',
});
return User;
};
In another file I have tried:
const {Sequelize, DataTypes} = require('sequelize');
const {sequelize} = require('../../database/connect');
const {userModel} = require('../../models/user');
function GetAll(UserName, Email){
var option = new userModel;
var option2 = new userModel(sequelize, DataTypes);
return "1";
}
But both give me this error:
TypeError: userModel is not a constructor at Object.GetAll (C:\Users\userone\Documents\Development\NodeJS\simple-express-project\data\userdata\userdata.js:8:16) at GetAll (C:\Users\userone\Documents\Development\NodeJS\simple-express-project\areas\directory\controllers\usercontroller.js:6:27) at Layer.handle [as handle_request] (C:\Users\userone\Documents\Development\NodeJS\simple-express-project\node_modules\express\lib\router\layer.js:95:5) at next (C:\Users\userone\Documents\Development\NodeJS\simple-express-project\node_modules\express\lib\router\route.js:137:13) at Route.dispatch (C:\Users\userone\Documents\Development\NodeJS\simple-express-project\node_modules\express\lib\router\route.js:112:3) at Layer.handle [as handle_request] (C:\Users\userone\Documents\Development\NodeJS\simple-express-project\node_modules\express\lib\router\layer.js:95:5) at C:\Users\userone\Documents\Development\NodeJS\simple-express-project\node_modules\express\lib\router\index.js:281:22 at Function.process_params (C:\Users\userone\Documents\Development\NodeJS\simple-express-project\node_modules\express\lib\router\index.js:341:12) at next (C:\Users\userone\Documents\Development\NodeJS\simple-express-project\node_modules\express\lib\router\index.js:275:10) at Function.handle (C:\Users\userone\Documents\Development\NodeJS\simple-express-project\node_modules\express\lib\router\index.js:174:3)
Edit 1
If I remove new from them, I get the error: userModel is not a function.
Edit 2
Based on the recommendation by Luka Cerruti, I have changed my user.js like this:
module.exports.UserModel
And in the other file,
function GetAll(UserName, Email){
console.log(UserModel);
const user = UserModel(sequelize, DataTypes);
console.log(user);
return "1";
}
But a new error appeared:
TypeError: Cannot read properties of undefined (reading 'define') at Function.init (C:\Users\userone\Documents\Development\NodeJS\simple-express-project\node_modules\sequelize\lib\model.js:663:53) at Function.init (C:\Users\userone\Documents\Development\NodeJS\simple-express-project\models\user.js:17:15) at module.exports.UserModel (C:\Users\userone\Documents\Development\NodeJS\simple-express-project\models\user.js:41:8) at Object.GetAll (C:\Users\userone\Documents\Development\NodeJS\simple-express-project\data\userdata\userdata.js:8:16) at GetAll (C:\Users\userone\Documents\Development\NodeJS\simple-express-project\areas\directory\controllers\usercontroller.js:6:27) at Layer.handle [as handle_request] (C:\Users\userone\Documents\Development\NodeJS\simple-express-project\node_modules\express\lib\router\layer.js:95:5) at next (C:\Users\userone\Documents\Development\NodeJS\simple-express-project\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Users\userone\Documents\Development\NodeJS\simple-express-project\node_modules\express\lib\router\route.js:112:3) at Layer.handle [as handle_request] (C:\Users\userone\Documents\Development\NodeJS\simple-express-project\node_modules\express\lib\router\layer.js:95:5) at C:\Users\userone\Documents\Development\NodeJS\simple-express-project\node_modules\express\lib\router\index.js:281:22
Solution 1:[1]
"use strict";
const { Sequelize, DataTypes } = require('sequelize');
const sequelize = require('../db.conn');
const Model = Sequelize.Model;
const UserProfile = require('./userProfile.model');
const InterviewSchedule = require('./interviewSchedule.model');
class User extends Model { }
User.init({
// Model attributes are defined here
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
name: {
type: DataTypes.STRING,
allowNull: false
},
mobile_num: {
type: DataTypes.STRING,
allowNull: false,
},
}, {
indexes: [
{
fields: ['mobile_num']
}
],
// Other model options go here
sequelize, // We need to pass the connection instance
tableName: 'users', // We need to choose the model name
paranoid: true, //soft deletion.
timestamps: true, // this will add created_at and updated_at fields in current table, and sequelize will update its values respectively.
});
//associations
User.hasMany(InterviewSchedule, {foreignKey: 'userId', sourceKey: 'id'});
User.hasOne(UserProfile, {foreignKey: 'userId', sourceKey: 'id'});
User.sync()
.then(() => {
console.log(`users table synced...`);
}).catch(err => {
console.log(err);
});
// the defined model is the class itself
console.log(User === sequelize.models.User); // true
module.exports = User;
This is the working code from my project. You can then call it by requiring it in other file like const UserModel = require('../database/models/user.model');
and query it like let userData = await UserModel.findOne({ where: { mobile_num: user.mobile_num } });
Solution 2:[2]
Try like this:
On user.js
// instead of
module.exports = 'bla bla bla'
// try
module.exports.userModel = 'bla bla bla'
on other files
const { userModel } = require('../../models/user');
// then use new userModel() to interact
or you can also let user.js just like it is right now and import it on other files like const userModel = require('../../models/user'); (without destructuring as it's default export)
For more information, check this answer: https://stackoverflow.com/a/40295288/18312347
Even if this works, I would personally recommend using import/export syntax... read more about it on https://javascript.info/import-export
Solution 3:[3]
If you won't like to change your user.js file
const {Sequelize, DataTypes} = require('sequelize');
const {sequelize} = require('../../database/connect');
const getUserModel = require('../../models/user');
function GetAll(UserName, Email){
var UserModel = getUserModel(sequelize, DataTypes); // this function return User model in user.js file
var option2 = new UserModel();
return "1";
}
If you can change your user.js file then you can export User model instead of arrow function and add static setter function to set sequelize, DataTypes, etc.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Ashish kushwaha |
| Solution 2 | |
| Solution 3 | Arif Khan |
