Home > OS >  ES6 How to declare an instance of a class inside a function
ES6 How to declare an instance of a class inside a function

Time:02-26

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:

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

CodePudding user response:

"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 } });

CodePudding user response:

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

CodePudding user response:

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.

  • Related