Art Bu
Art Bu

Reputation: 121

NestJS can't resolve dependencies - Can't get model repository into service

I have a pretty usual backend with NestJS. A User model has statuses associated with a Status model. So the Status is a separate module with model, module, controller and service files.

There is a Error when I launch the server:

ERROR [ExceptionHandler] Nest can't resolve dependencies of the StatusesService (?). Please make sure that the argument StatusRepository at index [0] is available in the StatusesService context.

Potential solutions:
- If StatusRepository is a provider, is it part of the current StatusesService?
- If StatusRepository is exported from a separate @Module, is that module imported within StatusesService?
  @Module({
    imports: [ /* the Module containing StatusRepository */ ]
  })


at Injector.lookupComponentInParentModules (/Users/macbook/WebstormProjects/getguitar/backend/node_modules/@nestjs/core/injector/injector.js:201:19)
at Injector.resolveComponentInstance (/Users/macbook/WebstormProjects/getguitar/backend/node_modules/@nestjs/core/injector/injector.js:156:33)
at resolveParam (/Users/macbook/WebstormProjects/getguitar/backend/node_modules/@nestjs/core/injector/injector.js:108:38)
at async Promise.all (index 0)
at Injector.resolveConstructorParams (/Users/macbook/WebstormProjects/getguitar/backend/node_modules/@nestjs/core/injector/injector.js:123:27)
at Injector.loadInstance (/Users/macbook/WebstormProjects/getguitar/backend/node_modules/@nestjs/core/injector/injector.js:52:9)
at Injector.loadProvider (/Users/macbook/WebstormProjects/getguitar/backend/node_modules/@nestjs/core/injector/injector.js:74:9)
at async Promise.all (index 0)
at InstanceLoader.createInstancesOfProviders (/Users/macbook/WebstormProjects/getguitar/backend/node_modules/@nestjs/core/injector/instance-loader.js:44:9)
at /Users/macbook/WebstormProjects/getguitar/backend/node_modules/@nestjs/core/injector/instance-loader.js:29:13

But StatusRepository is just a Status model repository, I don't have to make it a part of the StatusService. I have already added the Status model in to the module with SequelizeModule.forFeature([Status]) - just in the exact way as it explained in the official NestJS docs and it should do all the work:

import {Module} from '@nestjs/common';
import { StatusesService } from './statuses.service';
import {SequelizeModule} from "@nestjs/sequelize";
import {Status} from "./statuses.model";
import { StatusesController } from './statuses.controller';

@Module({
  providers: [StatusesService],
  controllers: [StatusesController],
  imports: [SequelizeModule.forFeature([Status])],
  exports: [StatusesService]
})
export class StatusesModule {}

But it does not. It is not a provider or any other stuff to be imported. I just don't see the problem, so I can't find the solution. It is interesting that the same way of introducing of the model repository works well for other models in this app, but Status acts like it special :)

Here is the service file, the Error is generated by this constructor of StatusesService class:

import {HttpException, HttpStatus, Injectable} from '@nestjs/common';
import {InjectModel} from "@nestjs/sequelize";
import {Status} from "./statuses.model";
import {CreateStatusDto} from "./dto/create-status.dto";

@Injectable()
export class StatusesService {

    constructor(@InjectModel(Status) private statusesRepository: typeof Status) {}

    async createStatus(dto: CreateStatusDto) {
        try {
            return await this.statusesRepository.create(dto)
        } catch (e) {
            throw new HttpException(`Error in createStatus: ${e}`, HttpStatus.INTERNAL_SERVER_ERROR)
        }
    }
}

And here is the Status model just for checking:

import {Column, DataType, HasMany, Model, Table} from "sequelize-typescript";
import {ApiProperty} from "@nestjs/swagger";
import {User} from "../users/users.model";
import {UserStatuses} from "../app.constants";

interface StatusCreationAttrs {
    value: string
    description: string
}

@Table({tableName: 'statuses', createdAt: false, updatedAt: false})
export class Status extends Model<Status, StatusCreationAttrs> {

    @ApiProperty({description: 'Unique ID', type: Number})
    @Column({type: DataType.INTEGER, unique: true, autoIncrement: true, primaryKey: true})
    id: number

    @ApiProperty({description: 'Unique value for the instance', enum: UserStatuses, required: true})
    @Column({type: DataType.ENUM({values: Object.keys(UserStatuses)}), unique: true, allowNull: false})
    value: string

    @ApiProperty({description: 'Description for the Status', type: String, required: true})
    @Column({type: DataType.STRING, allowNull: false})
    description: string

    @HasMany(() => User)
    users: User[]
}

Here is the app.module

import {Module} from '@nestjs/common';
import {SequelizeModule} from "@nestjs/sequelize"
import {ConfigModule} from "@nestjs/config"
import {AuthModule} from './auth/auth.module';
import {UsersModule} from './users/users.module';
import {TokensModule} from './tokens/tokens.module';
import {RolesModule} from './roles/roles.module';
import {TransactionsModule} from './transactions/transactions.module';
import {User} from "./users/users.model";
import {Transaction} from "./transactions/transactions.model";
import {Status} from "./statuses/statuses.model";
import {Role} from "./roles/roles.model";
import {Token} from "./tokens/tokens.model";
import { StatusesModule } from './statuses/statuses.module';

@Module({
    imports: [
        ConfigModule.forRoot({
            envFilePath: `.${process.env.NODE_ENV}.env`
        }),
        SequelizeModule.forRoot({
            dialect: "postgres",
            host: process.env.POSTGRES_HOST,
            port: Number(process.env.POSTGRESS_PORT),
            username: process.env.POSTGRES_USER,
            password: process.env.POSTGRESS_PASSWORD,
            database: process.env.POSTGRES_DB,
            models: [
                User,
                Status,
                Role,
                Transaction,
                Token
            ],
            autoLoadModels: true,
            synchronize: true
        }),
        AuthModule,
        UsersModule,
        TokensModule,
        RolesModule,
        TransactionsModule,
        StatusesModule,
    ],
    controllers: [],
    providers: [],
})
export class AppModule {
}

I would love to catch the problem. It seems to be something very simple, but I still have no glue about it. Thanks in advance!

Upvotes: 2

Views: 1496

Answers (1)

Jay McDoniel
Jay McDoniel

Reputation: 70450

From the error as described here in detail you have StatusesService in some module's imports array somewhere in your application. Remove it from the imports and only keep @Module() decorated classes (or dynamic modules) in the imports arrays

Upvotes: 1

Related Questions