I have been working on an API based on NestJS and here is a part of the code where I'm experiencing quite weird behaviour.
ISSUE: PagePartModule is NOT importing any module I add to imports (in this case ImageModule) and so I'm getting undefined when trying to inject ImageService in PagePartModule's resolver. Please see the code below:
// page-part.module.ts
@Module({
imports: [ImageModule],
providers: [PagePartImageResolver],
})
export class PagePartModule {}
// page-part-image.resolver.ts
@Resolver(of => PagePartImage)
export class PagePartImageResolver {
constructor(
private readonly imageService: ImageService
) {}
@ResolveProperty('image', type => Image, { nullable: true })
async image(@Root() pagePart: PagePart) {
// NOTE: pagePart is filled with correct data
// ERROR: "Cannot read property 'find' of undefined",
// this.imageService is undefined
return await this.imageService.find({ id: pagePart.imageId });
}
}
// image.module.ts
@Module({
imports: [DataloaderModule],
providers: [ImageResolver, ImageService],
exports: [ImageService],
})
export class ImageModule {}
// image.service.ts
@Injectable()
export class ImageService {}
Note that I'm:
1) Adding ImageService in ImageModule exports decorator
2) ImageService is decorated with @Injectable()
3) Importing the ImageModule (which provides ImageService) via imports on PagePartModule
4) Injecting ImageService via constructor in page-part-image.resolver.ts
What I have tried:
- No error is thrown by NestJS on build time; Once I query the resolvers "image" field error shows up - saying Cannot read property 'find' of undefined
-> imageService is undefined: not injected.
- If I inject the ImageModule to other module everything works as expected.
- Even if I create a service which is part of the PagePartModule, and put it in the PagePartModule providers it's still not injected into the specified resolver - which is weird (but trying to import the created service to other module again works as expected).
- "emitDecoratorMetadata": true
exists in my tsconfig.json
I believe I'm doing everything that is needed for the injection to work. (The API has over dozen modules in which I use the same approach and it works as expected)
I would appreciate any guidance for what could be causing the problem.
"dependencies": {
"@nestjs/common": "^6.8.3",
"@nestjs/core": "^6.8.3",
"@nestjs/graphql": "^6.5.3",
"@nestjs/jwt": "^6.1.1",
"@nestjs/passport": "^6.1.0",
"@nestjs/platform-express": "^6.8.3",
"@nestjs/typeorm": "^6.2.0",
"apollo-server-express": "^2.9.6",
"aws-sdk": "^2.551.0",
"axios": "^0.19.0",
"crc-32": "^1.2.0",
"dataloader": "^1.4.0",
"dotenv": "^8.2.0",
"graphql": "^14.5.8",
"graphql-tools": "^4.0.5",
"helmet": "^3.21.1",
"lodash": "^4.17.15",
"nestjs-redis": "^1.2.3",
"passport": "^0.4.0",
"passport-jwt": "^4.0.0",
"passport-local": "^1.0.0",
"pg": "^7.12.1",
"reflect-metadata": "^0.1.12",
"rimraf": "^2.6.2",
"rxjs": "^6.3.3",
"type-graphql": "^0.17.5",
"typeorm": "^0.2.19",
"uuid": "^3.3.3"
},
"devDependencies": {
"@nestjs/testing": "^6.0.0",
"@types/express": "^4.16.0",
"@types/jest": "^23.3.13",
"@types/node": "^10.14.22",
"@types/supertest": "^2.0.7",
"axios-mock-adapter": "^1.17.0",
"concurrently": "^4.1.0",
"jest": "^24.9.0",
"nodemon": "^1.19.4",
"prettier": "^1.15.3",
"supertest": "^3.4.1",
"ts-jest": "24.0.2",
"ts-loader": "^6.2.0",
"ts-node": "8.1.0",
"tsconfig-paths": "3.8.0",
"tslint": "5.16.0",
"typescript": "3.4.3",
"wait-on": "^3.2.0",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.9",
"webpack-node-externals": "^1.7.2"
},
ResolveProperty
you have aQuery
or aMutation
that is called first, and this is telling GraphQL how to resolve this property of that object. It looks like there is no query being executed, but I'm not 100% sure on that. Have you verified that the property from@Root()
is defined as well? Still not sure why theImageService
would be null, everything else looks correct. – Jay McDoniel