Nest can't resolve dependencies of the XXX after upgrade from 8 to 9 - node.js

Nestjs app stop working after upgrading from version 8 to 9
I recently upgraded my nestjs project from 8.x.x to 9.2.1
Since this moment my application stop working and I'm keep getting error: "Nest can't resolve dependencies of the XXX" in all of my resources.
Before I upgraded everything worked perfect.
[Nest] 410513 - 08/12/2022, 17:07:21 ERROR [ExceptionHandler] Nest can't resolve dependencies of the LoanService (PrismaService, ConfigService, StatusesHelper, LoanHelper, QuestionnaireHelper, EventEmitter, DATABASE_CONNECTION, ?). Please make sure that the argument Object at index [7] is available in the LoanModule context.
Here is my service DI constractor:
import { StatusesHelper } from 'src/helpers/statuses.service';
import { LoanHelper } from 'src/helpers/loan.service';
import { Db, ObjectId } from 'mongodb';
import { QuestionnaireHelper } from 'src/helpers/questionnaire.helper';
import { RunWeights } from 'src/deal/events/run-weights.event';
import { EventEmitter2 } from '#nestjs/event-emitter';
import { User } from '#prisma/client';
import { TwilioClient } from 'nestjs-twilio';
#Injectable()
export class LoanService {
constructor(
private prisma: PrismaService
, private config: ConfigService
, private statuses: StatusesHelper
, private readonly loanHelper: LoanHelper
, private questionnaireHelper: QuestionnaireHelper
, private readonly eventEmitter: EventEmitter2
, #Inject('DATABASE_CONNECTION') private db: Db
, private readonly twilio: TwilioClient
) { }
Can someone please help me figure it out?
thanks.

It happens most of the time due to either that module is not imported or there is a circular dependency.

Related

How to pass a #liaoliaots/nestjs-redis redis connection to global guard constructor

i'm new in NestJS and have some misunderstands with #liaoliaots/nestjs-redis(https://github.com/liaoliaots/nestjs-redis) package. For example, i have a guard with following constructor:
import { InjectRedis } from '#liaoliaots/nestjs-redis';
import { Redis } from 'ioredis';
#Injectable()
export class SomeGuard implements CanActivate {
constructor(#InjectRedis() redis: Redis) {}
...
}
and then i want that guard to be global:
//main.ts
...
app.useGlobalGuards(new SomeGuard(/* what??? */));
...
so thats a problem: what i need to pass? #InjectRedis makes weird things:)
thx for responding
Instead of app.useGlobalGuards, use this another way:
// ...
import { Module } from '#nestjs/common'
import { APP_GUARD } from '#nestjs/core'
#Module({
// ...
providers: [
{
provide: APP_GUARD,
useClass: SomeGuard,
},
],
})
export class AppModule {}
is cleaner and helps you avoid polluting your boostrap funcion. Also, it lets Nest resolves that Redis dependency. Otherwise you'll need to get this dependency and pass it to new SomeGuard using
const redis = app.get(getRedisToken())
https://docs.nestjs.com/guards#binding-guards

Connection "default" was not found - TypeORM, NestJS and external NPM Package

I'm using NestJs to create a couple of applications and I want to move the code from a NestInterceptor for an external NPM Package so I can use the same interceptor in multiple applications.
The problem is that the same code that works when used "locally" just stop working when moved to the external package.
Here's the code for the interceptor:
import { Injectable, NestInterceptor, CallHandler, ExecutionContext } from '#nestjs/common'
import { map } from 'rxjs/operators'
import { getManager } from 'typeorm'
import jwt_decode from 'jwt-decode'
#Injectable()
export class MyInterceptor implements NestInterceptor {
entity: any
constructor(entity: any) {
this.entity = entity
}
async intercept(context: ExecutionContext, next: CallHandler): Promise<any> {
const request = context.switchToHttp().getRequest()
const repository = getManager().getRepository(this.entity)
return next.handle().pipe(map((data) => data))
}
}
Here's a given controller:
import { myInterceptor } from "../src/interceptors/interceptor.ts";
#UseInterceptors(new CompanyIdInterceptor(User))
export class UserController {
}
This works fine, but if a move the file to an external NPM package and import from it like this:
import { myInterceptor } from "mynpmpackage";
I get the following error:
[Nest] 24065 - 04/18/2019, 10:04 AM [ExceptionsHandler] Connection "default" was not found. +26114ms
ConnectionNotFoundError: Connection "default" was not found.
at new ConnectionNotFoundError (/home/andre/Services/npm-sdk/src/error/ConnectionNotFoundError.ts:8:9)
at ConnectionManager.get (/home/andre/Services/npm-sdk/src/connection/ConnectionManager.ts:40:19)
Any ideas, on what causes this and how to solve it?
This might not be your problem exactly, but I had a similar problem when moving things to external packages with TypeORM. Make sure all packages from parent project are using the same version of the TypeORM package.
In my case, using yarn why typeorm showed me two different versions were being installed. One of them was used to register the entities, while the framework connected to the SQL database using another version, generating this clash.
Check your versions using yarn why [pkg-name] or if you're using NPM, try npx npm-why [pkg-name] or install globally from https://www.npmjs.com/package/npm-why.
After verifying TypeOrm versions is same in both the packages i.e- external package and consumer repository as mentioned by #Luís Brito still issue persist then issue could be-
Basically when we create an external package - TypeORM tries to get the "default" connection option, but If not found then throws an error:
ConnectionNotFoundError: Connection "default" was not found.
We can solve this issue by doing some kind of sanity check before establishing a connection - luckily we have .has() method on getConnectionManager().
import { Connection, getConnectionManager, getConnectionOptions,
createConnection, getConnection, QueryRunner } from 'typeorm';
async init() {
let connection: Connection;
let queryRunner: QueryRunner;
if (!getConnectionManager().has('default')) {
const connectionOptions = await getConnectionOptions();
connection = await createConnection(connectionOptions);
} else {
connection = getConnection();
}
queryRunner = connection.createQueryRunner();
}
Above is a quick code-snippet which was the actual root cause for this issue but If you are interested to see complete working repositories (different example) -
External NPM Package :
Git Repo : git-unit-of-work (specific file- src/providers/typeorm/typeorm-uow.ts)
Published in NPM : npm-unit-of-work
Consumer of above package : nest-typeorm-postgre (specific files- package.json, src/countries/countries.service.ts & countries.module.ts)

export/import javascript class like module node into electron with webpack

In context of basic electon-vue app, I want to create my own javascript class and use it into main process or renderer or into vue component.
I created JS Class but I never find a good way for exporting my class.
All possibility of writing import/export module find in the web finished by same error : Undefined exports
"use strict"
import fs from 'fs'
import typeorm from 'typeorm'
import Public from './../entity/Public'
class ConnectionManager
{
constructor(){}
getConnection(type, name, options) {
}
}
module.exports = ConnectionManager
But it seeams that others js file work perfectly like the vue-router js for routing into vue.js app :
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'home',
component: require('#/components/Home').default
}
]
})
I package my code with Webpack and libraryTarget Output is : commonjs2
I seems that use babel-loader with webpack
node version : 10.13.0
electron : 3.0.10
Babel : 6
EDIT :
I try this syntax class js file :
"use strict"
import * as fs from 'fs'
import * as typeorm from 'typeorm'
import {Public} from './../entity/Public'
export default class ConnectionManager
{
constructor(){}
getConnection(type, name, options) {
}
}
with this import syntax :
import ConnectionManager from './../service/connectionManager'
But I have this error when I execute code into electron :
Uncaught TypeError:
_service_connectionManager__WEBPACK_IMPORTED_MODULE_8__.default.getConnection
is not a function
I console logged this service class "ConnectionManager" and I have this result (so it really exist) :
ƒ ConnectionManager() {
babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_0___default()(this, ConnectionManager);
}
It seems that the final js module webpack contain the ConnectionManager class
It seems that you mix commonjs modules with ES modules by the wrong way.
There are a lot of modules (include node built-in) which have no default export. To import such a module you need to use * as moduleAlias or { exportedField } in your import statement. Try to rewrite your code by this way:
import * as fs from 'fs'
import * as typeorm from 'typeorm'
import { Public } from '../entity/Public'
export default class ConnectionManager
{
constructor(){}
getConnection(type, name, options) {
}
}
Because this class is exported as a default value, you can use the following construction to import it as a default field, where ConnectionManager is an alias for the current scope:
import ConnectionManager from '../service/connectionManager'

nest-schedule npm not working

I am using nest.js framework for developing a node based application. I am trying to write a scheduler using nest-schedule as mentioned at https://www.npmjs.com/package/nest-schedule.
Somehow the code is not working when used with #Cron or #Schedule. Rest other decorators work's fine. Using the same code base as mentioned in above link. Can anyone help me with setting this up and with exact cron pattern used in nodejs
For current version of Nest may you could use nestjs/schedule. See how I achieve this with nestjs/schedule.
1st: install nestjs cli
npm i -g #nestjs/cli
2nd: Create a new project
nest new schedule-sample
3rd: Install the nestjs schedule
npm install --save #nestjs/schedule
4th: Generate a new service to put your service.
nest generate service cron
Once you have installed the package add it to the app.module as follow below:
import { Module } from '#nestjs/common';
import { ScheduleModule } from '#nestjs/schedule';
import { Logger } from '#nestjs/common';
#Module({
imports: [
ScheduleModule.forRoot()
],
})
export class AppModule {}
5th: you can run it as show bellow (the complete instructions are here https://docs.nestjs.com/techniques/task-scheduling):
#Cron('*/5 * * * * *')
runEvery10Seconds() {
console.log('Run it every 5 seconds');
}
Here is the complete sample (cron.service.ts).
import { Logger } from '#nestjs/common';
import { Injectable } from '#nestjs/common';
import { Cron, Interval } from '#nestjs/schedule';
#Injectable()
export class CronService {
private readonly logger = new Logger(CronService.name);
#Cron('*/5 * * * * *')
runEvery10Seconds() {
this.logger.debug('Run it every 5 seconds');
}
#Cron('10 * * * * *')
handleCron() {
this.logger.debug('Called when the current second is 10');
}
#Interval(10000)
handleInterval() {
this.logger.debug('Called every 10 seconds');
}
}
Final thoughts:
The most sophisticated way to schedule jobs is use dynamic cron jobs. For that you can obtain a reference to a CronJob instance by name from anywhere in your code using the SchedulerRegistry API. First, inject SchedulerRegistry using standard constructor injection:
constructor(private schedulerRegistry: SchedulerRegistry) {}
HINT
Import the SchedulerRegistry from the #nestjs/schedule package.
Then use it in a class as follows. Assume a cron job was created with the following declaration:
#Cron('* * 8 * * *', {
name: 'notifications',
})
triggerNotifications() {}
Access this job using the following:
const job = this.schedulerRegistry.getCronJob('notifications');
job.stop();
console.log(job.lastDate());
I have tested it at the follow versions (package.json)
"#nestjs/common": "^7.6.15",
"#nestjs/core": "^7.6.15",
"#nestjs/schedule": "^0.4.3",
Had the same issue, cron jobs did not start, solved it this way:
async function bootstrap() {
const app = await NestFactory.createApplicationContext(AppModule);
// add this, if network if network listener is needed :
await app.listen(<port>)
// or this if network is not needed :
await app.init()
}
bootstrap();
Have you added your job's service to a module?
Maybe your job is not imported into any module.
https://github.com/nestjs/nest/tree/master/sample/27-scheduling/src/tasks
#Cron() and #Schedule() decorators did not really work until v0.3.1 (github issue).
Could you try the latest version?
package.json
{
...
"dependencies": {
"nest-schedule": "^0.3.1"
...
}
...
}
scheduler.service.ts
import { Injectable } from '#nestjs/common';
import { Cron, NestSchedule } from 'nest-schedule';
#Injectable()
export class SchedulerService extends NestSchedule {
// ...
#Cron('* * * * * *') // Run every second
scheduledJob() {
console.info('[Scheduler]: scheduled jobs has been started');
// ...
}
// ...
}
Works for me.
I had the same issue... Doing some research I found I need to use the latest version of #nestjs/common and #nestjs/core and if used also #nestjs/platform-express
Note that the decorator is used in the declarative definition.
NOT WORKING:
#Cron(CronExpression.EVERY_10_SECONDS)
async task() {
console.log('[Scheduler]: every 10 seconds');
}
WORKING:
#Cron(CronExpression.EVERY_10_SECONDS)
task() {
console.log('[Scheduler]: every 10 seconds');
}

cant import createBatchingNetworkInterface from apollo-client

I am trying to integrate graphql with my vue project.
I am following these instructions: https://github.com/Akryum/vue-apollo
I have npm installed 'apollo-client' as required, but for some reason i can't import 'createBatchingNetworkInterface'.
this is my main.js file:
import Vue from 'vue'
import { ApolloClient, createBatchingNetworkInterface } from 'apollo-client'
import VueApollo from 'vue-apollo'
import App from './App'
import router from './router'
and this is the index.d.ts file of my apollo-client:
export { print as printAST } from 'graphql/language/printer';
export { ObservableQuery, FetchMoreOptions, UpdateQueryOptions, ApolloCurrentResult } from './core/ObservableQuery';
export { WatchQueryOptions, MutationOptions, SubscriptionOptions, FetchPolicy, FetchMoreQueryOptions, SubscribeToMoreOptions, MutationUpdaterFn } from './core/watchQueryOptions';
export { NetworkStatus } from './core/networkStatus';
export * from './core/types';
export { ApolloError } from './errors/ApolloError';
import ApolloClient, { ApolloClientOptions } from './ApolloClient';
export { ApolloClientOptions };
export { ApolloClient };
export default ApolloClient;
I don't see here the 'createBatchingNetworkInterface' desired object.
I don't know what am i doing wrong here.
It sounds like you're using Apollo Client 2.0.You should downgrade to an older version (1.9.3) to continue using network interfaces, including the batching one.
The newest version of the client uses Links instead. You can check out the upgrade guide here if you are interested. you can still batch requests in 2.0 using apollo-link-batch-http.

Resources