I'm really new with typescript and sequelize, I follow Nestjs Sequelize guideline. Everything works fine for one model but when I want to associate between two model, there is an error while loading model.
users.entity.ts file
import { Table, Column, Model, DataType, Default, CreatedAt, UpdatedAt, DeletedAt, HasMany } from 'sequelize-typescript';
import { Token } from '../tokens/tokens.entity';
@Table
export class User extends Model<User> {
@Column({
type: DataType.CHAR(255),
allowNull: false
})
name: string;
@Column({
type: DataType.CHAR(255),
allowNull: false
})
email: string;
@Column({
type: DataType.CHAR(255),
allowNull: false
})
imageUrl: string;
@Column({
type: DataType.ENUM('male', 'female'),
allowNull: false
})
gender: string;
@Column({
type: DataType.CHAR(255),
allowNull: false
})
ageRange: string;
@Default(false)
@Column({
type: DataType.BOOLEAN
})
isAdmin: boolean;
@Default(false)
@Column({
type: DataType.BOOLEAN
})
isDeleted: boolean;
@CreatedAt
createdAt: Date;
@UpdatedAt
updatedAt: Date;
@DeletedAt
deletedAt: Date;
@HasMany(() => Token, 'userId')
tokens: Token[];
};
tokens.entity.ts
import { Table, Column, Model, DataType, Default, CreatedAt, UpdatedAt, ForeignKey, BelongsTo } from 'sequelize-typescript';
import { User } from '../users/users.entity';
@Table
export class Token extends Model<Token> {
@Column({
type: DataType.TEXT('medium'),
allowNull: false
})
accessToken: string;
@Column({
type: DataType.TEXT('medium'),
allowNull: false
})
refreshToken: string;
@ForeignKey(() => User)
@Column
userId: number;
@BelongsTo(() => User, 'userId')
user: User;
@CreatedAt
createdAt: Date;
@UpdatedAt
updatedAt: Date;
};
error log
TypeError: Cannot read property 'userId' of undefined
at new HasMany (/Users/win/sr-api/node_modules/sequelize/lib/associations/has-many.js:76:39)
at Function.hasMany (/Users/win/sr-api/node_modules/sequelize/lib/associations/mixin.js:26:25)
at Function._target.(anonymous function) [as hasMany] (/Users/win/sr-api/node_modules/sequelize-typescript/lib/models/BaseModel.js:35:41)
at Object.processAssociation (/Users/win/sr-api/node_modules/sequelize-typescript/lib/services/association.js:183:32)
at /Users/win/sr-api/node_modules/sequelize-typescript/lib/models/BaseSequelize.js:80:80
at Array.forEach (<anonymous>)
at /Users/win/sr-api/node_modules/sequelize-typescript/lib/models/BaseSequelize.js:80:26
at Array.forEach (<anonymous>)
at Sequelize.BaseSequelize.associateModels (/Users/win/sr-api/node_modules/sequelize-typescript/lib/models/BaseSequelize.js:76:16)
at Sequelize.BaseSequelize.addModels (/Users/win/sr-api/node_modules/sequelize-typescript/lib/models/BaseSequelize.js:62:14)
at Object.<anonymous> (/Users/win/sr-api/src/modules/database/database.providers.ts:18:23)
at Generator.next (<anonymous>)
at /Users/win/sr-api/src/modules/database/database.providers.ts:7:71
at Promise (<anonymous>)
at __awaiter (/Users/win/sr-api/src/modules/database/database.providers.ts:3:12)
at Object.useFactory [as metatype] (/Users/win/sr-api/src/modules/database/database.providers.ts:9:32)
at Injector.<anonymous> (/Users/win/sr-api/node_modules/@nestjs/core/injector/injector.js:82:59)
at Generator.next (<anonymous>)
at /Users/win/sr-api/node_modules/@nestjs/core/injector/injector.js:7:71
at Promise (<anonymous>)
at __awaiter (/Users/win/sr-api/node_modules/@nestjs/core/injector/injector.js:3:12)
at resolveConstructorParams (/Users/win/sr-api/node_modules/@nestjs/core/injector/injector.js:77:98)
1: node::Abort() [/usr/local/bin/node]
2: node::Chdir(v8::FunctionCallbackInfo<v8::Value> const&) [/usr/local/bin/node]
3: v8::internal::FunctionCallbackArguments::Call(void (*)(v8::FunctionCallbackInfo<v8::Value> const&)) [/usr/local/bin/node]
4: v8::internal::MaybeHandle<v8::internal::Object> v8::internal::(anonymous namespace)::HandleApiCallHelper<false>(v8::internal::Isolate*, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::FunctionTemplateInfo>, v8::internal::Handle<v8::internal::Object>, v8::internal::BuiltinArguments) [/usr/local/bin/node]
5: v8::internal::Builtin_Impl_HandleApiCall(v8::internal::BuiltinArguments, v8::internal::Isolate*) [/usr/local/bin/node]
6: 0x2c597d3040dd
7: 0x2c597d3f35e9
I know that it's similar to #144 but I can't seem to fix it
Another thing I'm curious modelPaths Can i exclude some folder in that command?
Hey @thestrayed, can you show me how you added the models to the seuqelize instance? Do you use a path or a class reference?
In case of a path you either need to use the same filename as model name (User.ts) or if using another file name, you need to default export your model (export default class User {...})
Excluding is currently not possible, but you can use globs https://github.com/RobinBuschmann/sequelize-typescript/blob/master/README.md#globs
@RobinBuschmann
This is how I add model in provider
import { Sequelize } from 'sequelize-typescript';
import { Token } from '../tokens/tokens.entity';
import { User } from '../users/users.entity';
export const databaseProviders = [
{
provide: 'SequelizeInstance',
useFactory: async () => {
const sequelize = new Sequelize({
dialect: 'mysql',
host: process.env.DB_HOST,
port: parseInt(process.env.DB_PORT),
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
});
sequelize.addModels([User]);
sequelize.addModels([Token]);
await sequelize.sync();
return sequelize;
}
}
];
Ah ok, this is the issue. You need to add them at once like sequelize.addModels([User, Token]). When addModels is called, sequelize tries to resolve all associations related to the passed models.
But of course, this is not a sufficient error message.
It works now with sequelize.addModels([User, Token]); Thank you
HI @RobinBuschmann
is it possible to add this use case in examples which you have shared. I also struggled quite a few hours & might be same case with many others
Most helpful comment
Ah ok, this is the issue. You need to add them at once like
sequelize.addModels([User, Token]). WhenaddModelsis called, sequelize tries to resolve all associations related to the passed models.But of course, this is not a sufficient error message.