Nest can't resolve dependencies of the PhotoService (?)

I'm starting with Nest.js and I'm getting an error after I create a service:

Nest can't resolve dependencies of the PhotoService (?). Please verify whether [0] argument is available in the current context.

I'm following the database example: https://docs.nestjs.com/techniques/database

Here is my full code: https://github.com/marceloHashzen/nestjsbasics

Upvotes: 48

Views: 83343

Answers (7)

whalemare
whalemare

Reputation: 1326

In my case, IDE automatically import type instead actual class, so it's not existed in runtime as argument

Broken code

import type { MyService } from '../my.service'

Working code

import { MyService } from '../my.service'

Upvotes: 1

Bersan
Bersan

Reputation: 3487

I'm using mongoose for the models. For me, this was due to missing imports for the model I declared:

@Module({
  imports: [MongooseModule.forFeature([{ name: 'ModelName', schema: ModelNameSchema }])], // <-- THIS WAS MISSING
  providers: [ModelNameService],
  controllers: [ModelNameController]
})
export class ModelNameModule {}

Upvotes: 0

Gabriel Arghire
Gabriel Arghire

Reputation: 2370

Pay attention to the order you are importing your services

If you import your services like this in shared.module.ts

// shared.module.ts

MyServiceOne
MyServiceTwo

make sure that you also declare them in the same order in the constructor.

// my-service-one.service.ts

export class MyServiceOne {
  constructor(@InjectModel(MyOne.name) private myOneModel: Model<MyOneModelDocument>,
    private myServiceTwo: MyServiceTwo) {}
}

Upvotes: 5

VMois
VMois

Reputation: 4708

In your app.module.ts remove PhotoService from providers. Then in PhotoModule, just export PhotoService:

@Module({
  // ...prev code
  exports: [PhotoService],
})

Upvotes: 72

Sergei Gannochenko
Sergei Gannochenko

Reputation: 11

Hit the same problem when making an application without sub-modules (just an application module).

My workaround was to obtain the repository from the connection.

import { Injectable } from '@nestjs/common';
import { Repository, Connection } from 'typeorm';
import { AuthorEntity } from '../entities/AuthorEntity';

@Injectable()
export class AuthorsService {
    usersRepository: Repository<AuthorEntity>;

    constructor(private connection: Connection) {
        this.usersRepository = connection.getRepository(AuthorEntity);
    }
...
}

Upvotes: 1

Pedro Luz
Pedro Luz

Reputation: 2772

Please remove any providers and controllers from app.module.ts. Even if they were added by the CLI tool.

In app.module.ts you are only supposed to load other modules in the imports

imports: [
  WaterModule,
  FireModule,
  AirModule,
  EarthModule,
]

Is up to each specific module to explicit define what imports, providers and exports can be used.

in: fire.module.ts

@Module({
  imports: [TypeOrmModule.forFeature([FireRepository])],
  controllers: [FireController],
  providers: [FireService],
  exports: [FireService],
})
export class FireModule {}

Upvotes: 7

Michael Czolko
Michael Czolko

Reputation: 2858

What helped me was in test use mock of PhotoService. Documentation was helpful https://docs.nestjs.com/fundamentals/custom-providers

Or have a look on the test spec I've wrote.

import { Test, TestingModule } from '@nestjs/testing';
import { PhotoController } from './photo.controller';
import { PhotoService } from './photo.service';

describe('PhotoController', () => {
  let module: TestingModule;
  let photoController: PhotoController;
  let photoService: PhotoService;

  const resultAll = ['test'];

  const mockPhotoService = {
    findAll: () => (resultAll),
  };

  const photoServiceProvider = {
    provide: PhotoService,
    useValue: mockPhotoService,
  };

  beforeAll(async () => {
    module = await Test.createTestingModule({
      controllers: [PhotoController],
      providers: [photoServiceProvider],
    }).compile();

    photoService = module.get<PhotoService>(PhotoService);
    photoController = module.get<PhotoController>(PhotoController);
  });

  describe('findAll', () => {
    it('should return collection of photos', async () => {
      jest.spyOn(photoService, 'findAll').mockImplementation(() => resultAll);

      expect(await photoController.findAll()).toBe(resultAll);
    });
  });
});

Let me know if it helped you as well

Upvotes: 6

Related Questions