Sequelize ModelNotInitializedError: Model not initialized - node.js

I'm trying to instantiate a new object of my Product model in my service but I got error:
`
ModelNotInitializedError: Model not initialized: Product cannot be instantiated. "Product" needs to be added to a Sequelize instance.
`
There is my sequelize config
I'm ussing repository mode and build the path that contain my models.
import { join } from "path";
import { Config } from "sequelize";
import { Sequelize } from "sequelize-typescript";
const path = join(__dirname, '..', '/entities/models/*.model.ts')
const sequelize = new Sequelize({
repositoryMode: true,
dialect: 'postgres',
host: 'localhost',
database: 'postgres',
port: 5432,
schema: 'store',
username: 'postgres',
password: '123.',
models: [path],
modelMatch: (filename, member) => {
return filename.substring(0, filename.indexOf('.model')).toLowerCase() === member.toLowerCase();
},
hooks: {
afterConnect: async (connection: Sequelize, _config: Config) => {
try {
await connection.query('set search_path = store')
} catch (error) {
console.log('Error at set search path: ', error)
}
}
}
})
export { sequelize }
There are my classes.
Product model, this model I attemp to instantiate.
import { Table, Column, Model, BelongsToMany } from 'sequelize-typescript'
import { Category, CategoryProduct } from './index'
#Table({
timestamps: false,
modelName: 'tal_product',
freezeTableName: true,
underscored: true
})
export class Product extends Model {
#Column({ primaryKey: true })
id!: number
#Column
name!: string
#Column
stock!: number
#Column({ field: 'is_active' })
isActive?: boolean
#BelongsToMany(() => Category, () => CategoryProduct)
categories?: Category[]
}
Product repository, here I have all my querys.
import { Repository } from 'sequelize-typescript'
import { Category, Product } from '../../../entities/models'
import { sequelize } from '../adminModule'
import { ProductRepository } from './product.repository'
export class ProductRepositoryImp implements ProductRepository {
productRepository: Repository<Product>
categoryRepository: Repository<Category>
constructor() {
this.productRepository = sequelize.getRepository(Product)
this.categoryRepository = sequelize.getRepository(Category)
}
create = async (product: Product): Promise<Product> => {
return await this.productRepository.create({ ...product })
}
}
product service, here I call the producRepository and instantiate my model
import { ICreateProduct, IProduct } from '../../../dto/product.dto'
import { Product } from '../../../entities/models'
import { ProductRepository } from '../repositories'
import { ProductServices } from './product.services'
export class ProductServicesImp implements ProductServices {
private productRepository: ProductRepository
public constructor(productRepository: ProductRepository) {
this.productRepository = productRepository
}
create = async (productDto: ICreateProduct): Promise<IProduct> => {
const product = new Product()
product.name = productDto.name
product.stock = productDto.stock
return await this.productRepository.create(product)
}
}
In ProductServicesImp when I instantiate a 'new Product()' I got the error.

Related

ERROR [ExceptionsHandler] Cannot query across many-to-many for property permissions

I have a project that I have made the project with nestjs and now I have a problem in method's update and the relation is Many-To-Many when I call Put Api nest gives me below error Note: I have 2 entity Role and Permission that they have many-to-many relation together.
I have a update method in role-service that I commented on it that works well but I have made a abstract class and role-service extended it but the method update doesn't work and give me bellow error
request api => url/api/role/id Body => {name:"admin",permissions:[{"id":1},{"id":2}]}
ERROR [ExceptionsHandler] Cannot query across many-to-many for property permissions
-Role Entity
import { Permission } from 'src/permission/model/permission.entity';
import {
Column,
Entity,
JoinTable,
ManyToMany,
PrimaryGeneratedColumn,
} from 'typeorm';
#Entity('roles')
export class Role {
#PrimaryGeneratedColumn()
id: number;
#Column()
name: string;
#ManyToMany((_Type) => Permission, { cascade: true })
#JoinTable({
name: 'role_permissions',
joinColumn: { name: 'role_id', referencedColumnName: 'id' },
inverseJoinColumn: { name: 'permission_id', referencedColumnName: 'id' },
})
permissions: Permission[];
}
Permission Entity
#Entity('permissions')
export class Permission {
#PrimaryGeneratedColumn()
id: number;
#Column()
name: string;
}
Role Controller
import {
Body,
Controller,
Delete,
Get,
Param,
Post,
Put,
UseGuards,
} from '#nestjs/common';
import { AuthGuard } from 'src/auth/auth.guard';
import { RoleCreateDto } from './models/role-create.dto';
import { RoleUpdateDto } from './models/role-update.dto';
import { Role } from './models/role.entity';
import { RoleService } from './role.service';
#UseGuards(AuthGuard)
#Controller('roles')
export class RoleController {
constructor(private roleService: RoleService) {}
#Put(':id')
async update(#Param('id') id: number, #Body() body: RoleUpdateDto) {
await this.roleService.update(id,body);
return await this.roleService.findOne({ id });
}
}
Role service
import { Injectable } from '#nestjs/common';
import { InjectRepository } from '#nestjs/typeorm';
import { AbstractService } from 'src/common/abstract.service';
import { Repository } from 'typeorm';
import { RoleCreateDto } from './models/role-create.dto';
import { Role } from './models/role.entity';
#Injectable()
export class RoleService extends AbstractService {
constructor(
#InjectRepository(Role) private readonly roleRepository: Repository<Role>,
) {
super(roleRepository)
}
async findOne(condition): Promise<Role> {
return await this.roleRepository.findOne({ where: condition , relations:["permissions"]});
}
// async update(id: number, data:any): Promise<any> {
// console.log(id);
// const role = await this.findOne({id});
// console.log(role);
// role.name = data.name;
// role.permissions= data.permissions;
// const r = await this.roleRepository.preload(role)
// console.log("role",r);
// return await this.roleRepository.save(r);
// }
// async delete(id: number): Promise<any> {
// return await this.roleRepository.delete(id);
// }
}
abstract service
import { Injectable } from '#nestjs/common';
import { Repository } from 'typeorm';
import { PaginatedResult } from './pagibated-result.interface';
#Injectable()
export abstract class AbstractService {
protected constructor(protected readonly repository: Repository<any>) {}
async all(): Promise<any[]> {
return await this.repository.find();
}
async paginate(page = 1): Promise<PaginatedResult> {
const take = 1;
const [data, total] = await this.repository.findAndCount({
take,
skip: (page - 1) * take,
});
return {
data: data,
meta: {
total,
page,
last_page: Math.ceil(total / take),
},
};
}
async create(data): Promise<any> {
return await this.repository.save(data);
}
async findOne(condition): Promise<any> {
return await this.repository.findOne({ where: condition });
}
async update(id: number, data): Promise<any> {
return await this.repository.update({id},data);
}
async delete(id: number): Promise<any> {
return await this.repository.delete(id);
}
}

Error: No repository for "AuditLogEntity" was found. Looks like this entity is not registered in current "default" connection? Typeorm

I created a new module in my codebase called as AuditLog, created using nest CLI and i get this error when i compile the code (nest start)
I created it inside src folder (refer screen shot),
here's my ormConfig
module.exports = {
type: 'postgres',
host: host || 'localhost',
username: username || 'postgres',
password: password || 'secret',
port: port || '5432',
database: pathname || 'dbname',
entities: ['src/**/*.entity.ts'],
migrationsTableName: 'migrations',
migrations: [`src/db/${migrationDir}/*.ts`],
cli: {
entitiesDir: 'src/*/',
migrationsDir: `src/db/${migrationDir}`
},
ssl: process.env.NODE_ENV === 'production'
? { rejectUnauthorized: false }
: false
};
Here's my entity definition
import { BaseEntity, Column, Entity, PrimaryColumn } from 'typeorm';
#Entity('auditlog')
export class AuditLogEntity extends BaseEntity {
#PrimaryColumn('uuid')
id: string;
#Column()
entityId: string;
#Column({ type: 'json' })
oldValue: Record<string, any>;
#Column()
entityType: string;
#Column()
updatedAt: Date;
}
Module code
import { Module } from '#nestjs/common';
import { TypeOrmModule } from '#nestjs/typeorm';
import { AuditLogEntity } from './audit-log.entity';
import { AuditLogController } from './audit-log.controller';
import { AuditLogService } from './audit-log.service';
#Module({
imports: [TypeOrmModule.forFeature([AuditLogEntity])],
controllers: [AuditLogController],
providers: [AuditLogService]
})
export class AuditLogModule {}
controller
import { Controller, Get } from '#nestjs/common';
import { AuditLogEntity } from './audit-log.entity';
import { AuditLogService } from './audit-log.service';
#Controller('api/audit-log')
export class AuditLogController {
constructor(private readonly auditLogService: AuditLogService) {}
#Get()
public async createAudit() {
const auditEntity = new AuditLogEntity();
// put this inside a static method that returns AuditLogEntity object taking AuditLogDto
auditEntity.entityId = '01b44c5d-158c-4719-806d-966652d408dc';
auditEntity.entityType = 'order';
auditEntity.oldValue = {
transporterId: '7d07b3e3-bd1f-4209-a1fa-414c5a019f52', // t04
phoneNumber: 9876534201
};
auditEntity.updatedAt = new Date();
return await this.auditLogService.addAuditEntity(auditEntity);
}
}
service file
import { Injectable } from '#nestjs/common';
import { InjectRepository } from '#nestjs/typeorm';
import { Repository } from 'typeorm';
import { AuditLogDto } from './audit-log.dto';
import { AuditLogEntity } from './audit-log.entity';
#Injectable()
export class AuditLogService {
constructor(
#InjectRepository(AuditLogEntity) private readonly auditRepository: Repository<AuditLogEntity>
) {}
public async addAuditEntity(auditEntity: AuditLogEntity): Promise<AuditLogEntity> {
return await this.auditRepository.save(auditEntity);
}
}
i have imported this module in app.module.ts too but still getting this error
Please help me here ...
please refer this file structure if required

Unable to mock typeorm datasource

Below is the file where I am trying to mock datasource. but Getting error as
TypeError: Cannot set property DataSource of [object Object] which has only a getter
import { AppService } from '../services';
import typeorm = require('typeorm');
describe("Tests for AppService", () => {
beforeAll(() => {
typeorm.DataSource = jest.fn().mockReturnValue({
manager: {
find: jest.fn(),
query: jest.fn(),
}
})
});
it("should call getServices", () => {
const AS = new AppService();
AS.getServices(1);
expect(typeorm.DataSource).toHaveBeenCalled();
});
})
datasource file
import { DataSource } from 'typeorm';
import { services } from '../entity/services';
import { versions } from '../entity/versions';
export const connectDB = new DataSource({
type: 'postgres',
host: 'localhost',
port: 5431,
username: 'postgres',
password: 'password',
database: 'test',
synchronize: true,
logging: true,
entities: [services, versions],
subscribers: [],
migrations: [],
});
connectDB
.initialize()
.then(() => {
console.log(`Data Source has been initialized`);
})
.catch((err) => {
console.error(`Data Source initialization error`, err);
});
export default connectDB;
And I am using it like,
import { Injectable } from '#nestjs/common';
import { Like } from 'typeorm';
import connectDB from '../config/db_connection';
import { services } from '../entity/services';
import { versions } from '../entity/versions';
// handle errors //
// write function description
#Injectable()
export class AppService {
public getServices(id: number): Promise<versions[]> {
return connectDB.manager.find(versions, {
relations: {
service: true,
Is there any better way to mock typeorm datasource in jest.
Thanks
This is the way I implement it in a repo of mine:
import { DataSource } from 'typeorm'
const makeDataSourceMock = (): DataSource => ({
name: 'any_data_source',
options: { database: 'any_database' },
destroy: jest.fn(),
manager: { save: jest.fn() },
getRepository: jest.fn(() => ({
clear: jest.fn()
})),
entityMetadatas: [
{ name: 'any_entity_name' }
]
}) as any
Here is the complete test file if you want to take a look: https://github.com/leal32b/webapi-nodejs/blob/main/test/core/3.infra/persistence/postgres/client/postgres-client.unit.test.ts

NestJS - TypeORM - Unable to track the Entity Not Found in TypeOrm & Nest.JS

No repository for "UserEntity" was found. Looks like
this entity is not registered in current "default" connection? +114ms
RepositoryNotFoundError: No repository for "UserEntity" was found. Looks like this entity is not registered in current "default" connection?
at RepositoryNotFoundError.TypeORMError [as constructor] (E:\Projects\...\src\error\TypeORMError.ts:7:9)
This is a Seed Method. It runs fine and add the data in the database, after adding data, I just get the error.
import { MediaEntity } from '../entities/media.entity';
import { Connection, Equal } from 'typeorm';
import { UserEntity } from '../entities/user.entity';
import { Helper } from '../services/helper';
export default async function UsersSeed(connection: Connection) {
const repository = connection.getRepository(UserEntity);
const data: Partial<UserEntity> = {
firstName: 'tesFName',
lastName: 'testLNsmr',
password: 'fafafa',
email: 'testmail#mail.com',
createdAt: Helper.dateToUTC(new Date())
};
let user = await repository.findOne({ email: data.email });
console.log("19");
console.log(user);
if (!user) {
const entity = Helper.createEntity(UserEntity, data);
console.log("23");
user = await repository.save(entity);
console.log("25");
} else {
console.log("27");
await repository.update(user.id, {
firstName: data.firstName,
lastName: data.lastName
});
console.log("33");
}
console.log("36");
const mediaRepository = connection.getRepository(MediaEntity);
await mediaRepository.update({ user: Equal(null) }, { user: user });
return user;
}
A bit more context:
It is being imported in app.module.ts as this.
#Module({
imports: [
ServeStaticModule.forRoot({
rootPath: join(__dirname, 'uploads')
}),
TypeOrmModule.forRootAsync({
useFactory: async (optionsService: OptionsService) =>
optionsService.typeOrmOptions(),
imports: [OptionsModule],
inject: [OptionsService]
}),
OptionsModule,
MediaModule,
AuthModule,
PlaceModule,
RepositoryModule,
ServicesModule
],
controllers: [],
providers: []
})
And then there is src/entities/entities.module.ts as:
const entities = [
UserEntity,
MediaEntity,
PlaceEntity,
DownloadRestrictionEntity,
MediaInfoEntity
];
#Module({
imports: [TypeOrmModule.forFeature(entities)],
exports: [TypeOrmModule.forFeature(entities)]
})
export class EntitiesModule {
}
Then src/options/options.service.ts as
#Injectable()
export class OptionsService {
constructor(
private service: ConfigService<IEnvironmentVariables>
) {
}
public typeOrmOptions(): TypeOrmModuleOptions {
const environment = process.env.NODE_ENV ? process.env.NODE_ENV : '';
const directory = this.directory();
return {
type: 'postgres',
host: this.service.get('POSTGRES_HOST'),
port: this.service.get('POSTGRES_PORT'),
username: this.service.get('POSTGRES_USER'),
password: this.service.get('POSTGRES_PASSWORD'),
database: this.service.get('POSTGRES_DATABASE'),
synchronize: false,
migrationsRun: this.service.get('RUN_MIGRATIONS'),
keepConnectionAlive: this.isTest(),
entities: [`${directory}/**/*.entity${environment ? '{.ts,.js}' : '{.js, .ts}'}`],
migrationsTableName: 'migrations',
migrations: [`${directory}/migrations/*.ts`],
cli: {
migrationsDir: 'src/migrations'
}
}
}
}
please create UserRepository typeorm-repository-pattern
Method 1:
#Injectable()
export class UsersService {
constructor(
#InjectRepository(User)
private usersRepository: Repository<User>,
) {}
}
Method 2: use BaseRepository from typeorm-transactional-cls-hooked
#EntityRepository(UserAdminEntity)
export class UserAdminRepository extends BaseRepository<UserAdminEntity> {}

Graphql Mysql - Get rows from a table in JSON Format

I'm working on Backend with TypeGraphQL and NodePostGres.
User will pass database id and table name. I need to send data in JSON Format.
I have tried below code but it doesn't return anything nor does it throw any error.
Service:
import { Service } from 'typedi'
import { Client } from 'pg'
import { databases } from './db'
import { Payload } from './models'
#Service()
export class PayloadService {
fetchPayload(id: number, tableName: string): Payload {
const databaseCredentials = databases.find((d) => d.id && +d.id === id)
if (!databaseCredentials) throw new Error('Invalid ID!')
const client = new Client({
host: databaseCredentials.host,
port: +(databaseCredentials.port || 5432),
user: databaseCredentials.username,
password: databaseCredentials.password,
database: databaseCredentials.database,
ssl: {
rejectUnauthorized: false,
},
})
console.log('before client')
client.query("select * from pg_tables where schemaname='public'", (err, res) => {
if (err) {
console.log(err.stack)
} else {
console.log(res.rows[0])
}
console.log(`callback`)
})
console.log('after client')
return {
id,
data: [],
}
}
}
Resolver:
import { Arg, Query, Resolver } from 'type-graphql'
import { Inject } from 'typedi'
import { Payload } from './models'
import { PayloadService } from './services'
#Resolver(Payload)
export class PayloadResolver {
#Inject()
private PayloadService: PayloadService
#Query((returns) => Payload)
payload(#Arg('databaseId') databaseId: number, #Arg('tableName') tableName: string) {
return this.PayloadService.fetchPayload(databaseId, tableName)
}
}

Resources