0

I get this error when i run my project.

ModelNotInitializedError: Model not initialized: Member "getTableName" cannot be called. "Categorie" needs to be added to a Sequelize instance.

User model :

import { Categorie } from './categorie.model';
import sequelize from './index'
import { Model } from 'sequelize-typescript'

interface UserAttributes {
  firstname: string;
  lastname: string;
  email: string;
  password: string;
  phone: string;
  address: string;
}


export class User extends Model<UserAttributes> implements UserAttributes {
  public firstname!: string;
  public lastname!: string;
  public email!: string;
  public password!: string;
  public phone!: string;
  public address!: string;

  public getCategories!: BelongsToManyGetAssociationsMixin<Categorie>;
  public addCategories!: BelongsToManyAddAssociationMixin<Categorie, number>;
  public hasCategories!: BelongsToManyHasAssociationMixin<Categorie, number>;
  public countCategories!: BelongsToManyCountAssociationsMixin;
  public createCategories!: BelongsToManyCreateAssociationMixin<Categorie>;

  public readonly createdAt!: Date;
  public readonly updatedAt!: Date;
}

User.init({
  // id: {
  //   type: DataTypes.INTEGER.UNSIGNED,
  //   autoIncrement: true,
  //   primaryKey: true,
  // },
  firstname: {
    type: new DataTypes.STRING(128),
    allowNull: false,
  },
  lastname: {
    type: new DataTypes.STRING(128),
    allowNull: false,
  },
  email: {
    type: new DataTypes.STRING(128),
    allowNull: false,
    unique: true,
  },
  password: {
    type: new DataTypes.STRING(128),
    allowNull: false,
  },
  phone: {
    type: new DataTypes.STRING(64),
    allowNull: false,
  },
  address: {
    type: new DataTypes.STRING(256),
    allowNull: false,
  },
}, {
  tableName: 'User',
  sequelize
})

User.belongsToMany(Categorie, {through: 'User_Cat'});
Categorie.belongsToMany(User, {through: 'User_Cat'});

sequelize.sync();

Categorie model :

import { BelongsToManyAddAssociationMixin, BelongsToManyCountAssociationsMixin, BelongsToManyCreateAssociationMixin, BelongsToManyGetAssociationsMixin, BelongsToManyHasAssociationMixin, DataTypes } from 'sequelize';
import sequelize from './index'
import { Model } from 'sequelize-typescript'
import { Unit } from './unit.model';

interface CategorieAttributes {
    index: number;
    title: string;
    img: string;
    label: string;
    eval_intro: string;
    eval_mid: string;
}

export class Categorie extends Model<CategorieAttributes> implements CategorieAttributes {
    public index!: number;
    public title!: string;
    public img!: string;
    public label!: string;
    public eval_intro!: string;
    public eval_mid!: string;

    public getUnits!: BelongsToManyGetAssociationsMixin<Unit>;
    public addUnits!: BelongsToManyAddAssociationMixin<Unit, number>;
    public hasUnits!: BelongsToManyHasAssociationMixin<Unit, number>;
    public countUnits!: BelongsToManyCountAssociationsMixin;
    public createUnits!: BelongsToManyCreateAssociationMixin<Unit>;

    public readonly createdAt!: Date;
    public readonly updatedAt!: Date;
}

Categorie.init({
    // id: {
    //     type: DataTypes.INTEGER.UNSIGNED,
    //     autoIncrement: true,
    //     primaryKey: true,
    // },
    index: {
        type: DataTypes.INTEGER.UNSIGNED,
        allowNull: true,
    },
    title: {
        type: new DataTypes.STRING(256),
        allowNull: false,
    },
    img: {
        type: new DataTypes.STRING(256),
        allowNull: true,
    },
    label: {
        type: new DataTypes.TEXT,
        allowNull: false,
    },
    eval_intro: {
        type: new DataTypes.STRING(256),
        allowNull: true,
    },
    eval_mid: {
        type: new DataTypes.STRING(256),
        allowNull: true,
    }
}, {
    tableName: 'Categorie',
    sequelize
})

Categorie.belongsToMany(Unit, { through: 'Cat_Unit' });
Unit.belongsToMany(Categorie, { through: 'Cat_Unit' });

sequelize.sync();

relation file :

interface UserCatAttributes {
    id: number;
    UserId: number;
    CategorieId: number;
    prog: number;
}


export class UserCat implements UserCatAttributes {
    public id!: number;
    public UserId!: number;
    public CategorieId!: number;
    public prog!: number;

    public readonly createdAt!: Date;
    public readonly updatedAt!: Date;
}

And my main file :

import express from 'express';
import { Express } from "express-serve-static-core";
import { Sequelize } from 'sequelize';
import { User } from './models/user.model';
import { Categorie } from './models/categorie.model';
import { Unit } from './models/unit.model';
import { UserCat } from './models/user_cat.model';
import { initRoutes } from './routes/index';
import { sequelize_config } from './config/sequelizeConfig';
import passport from 'passport';
import cors from 'cors';

const port: number = 8080;

class Beyond {

    public app: Express;
    public sequelize: Sequelize;

    constructor() {
        this.initApp()
    }

    initApp() {
        this.initExpress()
        this.initSequelize()
    }

    initExpress() {

        this.app = express();
        this.app.use(cors({
            optionsSuccessStatus: 200
        }))
        this.app.use(express.json());
        this.app.use(passport.initialize());
        this.app.use(passport.authenticate('session'));

        initRoutes(this.app);

        this.app.listen(port, () => {
            console.log("Serveur à l'écoute sur le port : ", port)
        })
    }

    async initSequelize() {
        this.sequelize = new Sequelize(
            sequelize_config.db_name,
            sequelize_config.db_user,
            sequelize_config.db_pw,
            sequelize_config.sequelize_info as any
        );
        await this.sequelize.authenticate().then(() => {
            console.log("Connexion ok")
        }).catch(err => {
            console.log("err connexion : ", err)
        })
    }
}




export const beyond = new Beyond();

All i want to do is a many to many relation, where User can have many Categorie and Categorie many User. What driving me crazy is everything was working perfectly before idk what event, the tables where created and all the backend has been made with thooses models

ex

export async function getCatByUserId(id: number): Promise<Array<Categorie>> {
  const user = await User.findByPk(id, { include: Categorie });
  return await user.getCategories();
}

and since then no way to make it works. I'am far for being a pro so any help is appreciated.

numba9
  • 1
  • 1

2 Answers2

1

You need to remove cross-references from model modules and define functions to register associations and call them after all your models will be registered in Sequelize instance.
See my answer here to get an idea of how to do it.

Anatoly
  • 20,799
  • 3
  • 28
  • 42
  • Thanks for the answer but i'am afraid i dont understand it. You are saying i need to remove the Categorie reference in User.model? What is bugging me is before this 'bug' happend, i had no trouble with creating models and relation this way. Sorry if i sound rough i'am just lost – numba9 Dec 13 '21 at 18:21
  • Nevertheless, It's better to define models as functions with a separate function to register associations and do it right after Sequelize instance was created. And definitely, you need to call `sync` only once after registering all models and their associations. – Anatoly Dec 13 '21 at 21:25
1

Use the

import { Sequelize } from 'sequelize'

instead

'sequelize-typescript'

it works for me.

Deepak Singh
  • 749
  • 4
  • 16
abasworks
  • 21
  • 4