Skip to content
Advertisement

Nest.js cant resolve dependencies, can’t find my mistake

I’m doing a Nest.js program but I can’t find my dependencies problem. I have searched quite a lot and I have found a lot of answers regarding this problem, but I can’t figure out why my code isn´t working. So I have a product module which has his DTO´s, Entity, Controller, Service and module, besides it has an interface for its service.

ProductController

import { Controller, Get } from '@nestjs/common';
import { ProductServiceInterface } from './interface/product.service.interface'

@Controller('products')
export class ProductController {
  constructor(private readonly productService: ProductServiceInterface) {}

  @Get()
  getHello(): string {
    return this.productService.test();
  }
}

ProductServiceInterface

import { Injectable } from '@nestjs/common';
import {
  CreateProductInput,
  CreateProductOutput,
} from '../dto/create-product.dto';
import { FindProductOutput } from '../dto/find-product.dto';

export interface ProductServiceInterface {
  create(input: CreateProductInput): Promise<CreateProductOutput>;
  findProduct(productId: string): Promise<FindProductOutput>;
  test();
}

ProductService

import { Injectable } from '@nestjs/common';
import { ProductServiceInterface } from './interface/product.service.interface';
import {
  CreateProductInput,
  CreateProductOutput,
} from './dto/create-product.dto';
import { Product } from './entity/product.entity';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { FindProductOutput } from './dto/find-product.dto';
//import WooCommerce from '../../config/woocomerce.config';

@Injectable()
export class ProductService implements ProductServiceInterface {
  constructor(
    @InjectRepository(Product)
    private productRepository: Repository<Product>,
  ) {}

  public async create(
    productDto: CreateProductInput,
  ): Promise<CreateProductOutput> {
    const product = new Product();
    product.name = productDto.name;
    product.price = productDto.price;
    product.imgUrl = productDto.imgUrl;

    const savedProduct = await this.productRepository.save(product);
    const productOutput = new CreateProductOutput();
    productOutput.id = savedProduct.id;
    return productOutput;
  }

  public async findProduct(idProduct: string): Promise<FindProductOutput> {
    const fetchedProduct = await this.productRepository.findOne(idProduct);
    const productOutput = new FindProductOutput();
    productOutput.id = fetchedProduct.id;
    productOutput.imgUrl = fetchedProduct.imgUrl;
    productOutput.name = fetchedProduct.name;
    productOutput.price = fetchedProduct.price;
    return productOutput;
  }

  public test() {
    return 'test'
    // WooCommerce.get('products', {
    //   pero_page: 20,
    // }).then((resp) => {
    //   return resp;
    // });
  }
}

ProductModule

import { ProductController } from './product.controller';
import { ProductService } from './product.service';
import { Product } from './entity/product.entity';

import { TypeOrmModule } from '@nestjs/typeorm';
import { Module } from '@nestjs/common';

@Module({
  imports: [TypeOrmModule.forFeature([Product])],
  controllers: [ProductController],
  providers: [ProductService],
})
export class ProductModule {}

AppModule

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from '@nestjs/config';
import configuration from 'src/config/configuration';
import { TypeOrmModule } from '@nestjs/typeorm';
import { TypeOrmConfigService } from 'src/config/typeorm.config.service';
import { ProductModule } from './modules/product/product.module';

@Module({
  imports: [
    ConfigModule.forRoot({
      load: [configuration],
      isGlobal: true,
    }),
    TypeOrmModule.forRootAsync({
      useClass: TypeOrmConfigService,
    }),
    ProductModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

I hope this code is enough for knowing where my mistake is, I don’t like letting others just resolve this for me but I’ve been watching my code for hours and can’t know how to resolve this dependencies problem.

Advertisement

Answer

Interfaces disappear at runtime and becomes {} or Object. Nest uses the parameter type metadata to determine what is supposed to be injected (usually via ClassType.name). You have two options to solve this

  1. Use an abstract class instead of an interface. This makes the class still visible at runtime so ClassType.name still works.

  2. Use @Inject('CustomToken') as the way to set the metadata for what Nest needs to inject. You then need to make sure register the custom provider using something like

{
  provide: 'CustomToken',
  useClass: ClassToBeUsed
}

Either of these methods should fix your issue.

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement