Я работаю над приложением NestJs, в котором я создал вспомогательный класс и использую функцию из класса модуля внутри этого вспомогательного класса. но я получаю некоторые ошибки. Сначала я получал неопределенную ошибку, затем я сделал вспомогательный класс инъекционным, а затем снова столкнулся с проблемами зависимостей.
Это ошибка, с которой я сталкиваюсь в настоящее время.
Error: Nest can't resolve dependencies of the BoomiService (?). Please make sure that the argument dependency at index [0] is available in the CronjobsModule context.
Potential solutions:
- If dependency is a provider, is it part of the current CronjobsModule?
- If dependency is exported from a separate @Module, is that module imported within
CronjobsModule?
@Module({
imports: [ /* the Module containing dependency */ ]
})
at Injector.resolveSingleParam (D:\WorkData\AGData\JavascriptProjects\orion\orion-gateway-api\node_modules\@nestjs\core\injector\injector.js:178:19)
at resolveParam (D:\WorkData\AGData\JavascriptProjects\orion\orion-gateway-api\node_modules\@nestjs\core\injector\injector.js:116:49)
at Array.map (<anonymous>)
at Injector.resolveConstructorParams (D:\WorkData\AGData\JavascriptProjects\orion\orion-gateway-api\node_modules\@nestjs\core\injector\injector.js:131:58)
at Injector.loadInstance (D:\WorkData\AGData\JavascriptProjects\orion\orion-gateway-api\node_modules\@nestjs\core\injector\injector.js:57:24)
at Injector.loadProvider (D:\WorkData\AGData\JavascriptProjects\orion\orion-gateway-api\node_modules\@nestjs\core\injector\injector.js:84:20)
at D:\WorkData\AGData\JavascriptProjects\orion\orion-gateway-api\node_modules\@nestjs\core\injector\instance-loader.js:47:62
at Array.map (<anonymous>)
at InstanceLoader.createInstancesOfProviders (D:\WorkData\AGData\JavascriptProjects\orion\orion-gateway-api\node_modules\@nestjs\core\injector\instance-loader.js:47:36)
at D:\WorkData\AGData\JavascriptProjects\orion\orion-gateway-api\node_modules\@nestjs\core\injector\instance-loader.js:32:24
at Array.map (<anonymous>)
at InstanceLoader.createInstances (D:\WorkData\AGData\JavascriptProjects\orion\orion-gateway-api\node_modules\@nestjs\core\injector\instance-loader.js:31:49)
at InstanceLoader.createInstancesOfDependencies (D:\WorkData\AGData\JavascriptProjects\orion\orion-gateway-api\node_modules\@nestjs\core\injector\instance-loader.js:21:20)
at D:\WorkData\AGData\JavascriptProjects\orion\orion-gateway-api\node_modules\@nestjs\core\nest-factory.js:96:38
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at Function.asyncRun (D:\WorkData\AGData\JavascriptProjects\orion\orion-gateway-api\node_modules\@nestjs\core\errors\exceptions-zone.js:22:13)
at NestFactoryStatic.initialize (D:\WorkData\AGData\JavascriptProjects\orion\orion-gateway-api\node_modules\@nestjs\core\nest-factory.js:94:13)
at NestFactoryStatic.create (D:\WorkData\AGData\JavascriptProjects\orion\orion-gateway-api\node_modules\@nestjs\core\nest-factory.js:37:9)
at bootstrap (D:\WorkData\AGData\JavascriptProjects\orion\orion-gateway-api\src\main.ts:9:15)
Это мой вспомогательный класс.
import axios from "axios";
import * as qs from'querystring';
import { OpenApiService } from "../open-api/open-api.service";
import {
BadRequestException,
Injectable,
NotFoundException,
} from '@nestjs/common';
@Injectable()
export class BoomiService {
constructor(private OpenApiService: OpenApiService) {}
//get services
//
//Post services
createRenewalRequest = async (data) => {
const config = {
headers: {
'Content-Type': 'application/json',
"x-api-key": process.env.BOOMI_APIKEY
}
};
// console.info('data',data)
try {
// console.info('here in createQRFeedbackForComm',config);
return axios.post(
`${process.env.BOOMI_API_BASEURL}${process.env.BOOMI_POST_APIENDPOINT}`,
JSON.stringify(data),
config
).then(async (response) => {
const boomilogs = await this.OpenApiService.saveOpenApiLogs({reason:response.data,reqData:data,type:'CXMRenewalRequest',status:'Completed'});
return response.data;
}).catch(async (e) => {
const boomilogs = await this.OpenApiService.saveOpenApiLogs({reason:e,reqData:data,type:'CXMRenewalRequest',status:'Failed'});
return (`error in createRenewalRequest => ${e}`);
});
} catch (e) {
const boomilogs = await this.OpenApiService.saveOpenApiLogs({reason:e,reqData:data,type:'CXMRenewalRequest',status:'Completed'});
throw e;
}
}
createMaintainenceRequest = async (data) => {
const config = {
headers: {
'Content-Type': 'application/json',
"x-api-key": process.env.BOOMI_APIKEY
}
};
try {
console.info('response->',this.OpenApiService)
// console.info('here in createQRFeedbackForComm',config);
return axios.post(
`${process.env.BOOMI_API_BASEURL}${process.env.BOOMI_POST_APIENDPOINT}`,
JSON.stringify(data),
config
).then(async (response) => {
const boomilogs = await this.OpenApiService.saveOpenApiLogs({reason:response.data,reqData:data,type:'CXMMaintainenceRequest',status:'Completed'});
return response.data;
}).catch(async (e) => {
console.info('response=',e)
const boomilogs = await this.OpenApiService.saveOpenApiLogs({reason:e,reqData:data,type:'CXMMaintainenceRequest',status:'Failed'});
return (`error in createMaintainenceRequest => ${e}`);
});
} catch (e) {
const boomilogs = await this.OpenApiService.saveOpenApiLogs({reason:e,reqData:data,type:'CXMMaintainenceRequest',status:'Failed'});
throw e;
}
}
}
здесь я использую метод saveOpenApiLogs
из OpenApiService
.
Это мой файл службы Open API.
import {
BadRequestException,
Injectable,
NotFoundException,
} from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import * as moment from 'moment';
import constants from '../config/constant';
import { CreateOpenApiDto } from './dto/create-open-api.dto';
import { UpdateOpenApiDto } from './dto/update-open-api.dto';
import { empty, firstValueFrom } from 'rxjs';
import { error } from 'console';
import { PropertyDto } from './dto/property.dto';
import utils from 'src/utils/utils';
import { util } from 'prettier';
import { CCAService } from 'src/utils/ccaService';
import {BoomiService} from 'src/utils/BoomiService';
import { v4 as uuidv4 } from "uuid";
var {
communityList,
nationalityList,
leaseNatureList,
leaseTypeList,
paymentScheduleArrName,
paymentStatusForAGP,
bhoomi_x_api_key,
} = constants;
const numberWithDastPattern = /^(\-?\d+)$/;
const mobileNumberPattern = /^(\+?\d+)$/;
@Injectable()
export class OpenApiService {
constructor(
private ccaService: CCAService,
private BoomiService: BoomiService,
private httpService: HttpService,
) {}
propertyAPI = process.env.PROPERTY_API;
userAPI = process.env.USER_API;
maintenanceAPI = process.env.MAINTENANCE_API;
leaseAPI = process.env.LEASING_API;
async sendMaintainenceNotificationToBoomi() {
let DataResponse = {},boomiResponse = {}
try {
const url = `${this.maintenanceAPI}ticket`;
let params: any = {};
params.todayTickets= true;
params.perPage= 100;
params.ticketStatus= 'issue_resolved,ag_not_responsible,landlord_not_responsible,reject';
let ticketData:any = await this.httpService
.get(
url, {params},
)
.toPromise()
.catch((e) => {
console.info('Error in todayTickets',e);
throw new Error(e.response.data.error);
});
// console.info('ticketData',ticketData.data.result.data);
if (ticketData && ticketData.data.result.data && ticketData.data.success) {
let tickets = ticketData.data.result.data;
let dataForBoomi:any[] = []
console.info('tickets -> length',tickets.length)
if (tickets.length>0){
await Promise.all(tickets.map(async (ticket) =>{
// console.info('ticket',ticket);
const url = `${this.userAPI}user/detail`;
const unit_url = `${this.propertyAPI}unit?unitId=${ticket?.unitId}&status=enable&select=propertyName,unit.unitNumber,address.community,address.subCommunity`;
let Tenant: any = await firstValueFrom(
this.httpService.post(url, {user:ticket?.tenantId}),
).catch((e) => {
console.info('ERROR---', e);
throw new Error(e.response.data.error);
});
// console.info('Tenant',Tenant?.data?.result)
let unit:any = await this.httpService
.get(
unit_url,
)
.toPromise()
.catch((e) => {
console.info('Error in get unit',e);
throw new Error(e.response.data.error);
});
// console.info('unit',unit?.data?.result.data[0])
dataForBoomi.push(
{
"firstName": Tenant?.data?.result?.name||"",
"lastName": Tenant?.data?.result?.name||"",
"fullName": Tenant?.data?.result?.name||"",
"emailId": Tenant?.data?.result?.email||"",
"whatsAppPhoneNumber": Tenant?.data?.result?.mobile||"",
"propertyType": "Residential",
"unitLeased": unit?.data?.result?.data[0]?.unit?.unitNumber||"",
"propertyName": unit?.data?.result?.data[0]?.propertyName||"",
"location": unit?.data?.result?.data[0]?.address?.community||"",
"subLocation": unit?.data?.result?.data[0]?.address?.subCommunity||"",
"communicationType": "Email",
"complaintType":"MAINTENANCE_REQUEST",
"complaintSubType": ticket?.ratingAndReview?.rating||'',
"businessUnit": "Properties",
"eventType": "MAINTENANCE_REQUEST",
"transactionDate": ticket?.updatedAt,
"categoryOfMaintenance": ticket?.category?.name||'',
"technicianAssigned": ticket?.technician?.name||'',
"attachmentURL": "",
"userType": "",
"comments": ticket?.ratingAndReview?.comment||''
}
);
// console.info('dataForBoomi',dataForBoomi)
return dataForBoomi
})).then(async (dataForBoomi) => {
// console.info('dataForBoomi',dataForBoomi)
let PayloadForBoomi = {
"QRCodeFeedback": dataForBoomi[0]
}
// console.info('PayloadForBoomi',PayloadForBoomi)
boomiResponse = await this.BoomiService.createMaintainenceRequest(PayloadForBoomi)
// console.info('boomiResponse:',boomiResponse)
console.info('------boomiResponse-----', boomiResponse);
DataResponse = boomiResponse;
return DataResponse
})
.catch(error => {
console.error('Error:', error);
});
}
}
} catch (error) {
DataResponse = error;
}
return {
DataResponse
};
}
async saveOpenApiLogs(reqBody=null){
console.info('reqBody',reqBody)
return await firstValueFrom(
this.httpService.post(`${this.userAPI}openAPItenantStatus`, {
uuid: uuidv4(),
reason: reqBody?.reason||'',
request: reqBody?.reqData?JSON.stringify(reqBody.reqData):'',
type: reqBody?.type||'',
status: reqBody?.status||'pending',
}),
).catch((e) => {return e});
}
}
Я удалил ненужные методы из этого класса, иначе код был бы беспорядочным.
это мой файл открытого модуля API, в который я импортировал вспомогательный класс.
import { Module } from '@nestjs/common';
import { OpenApiService } from './open-api.service';
import { OpenApiController } from './open-api.controller';
import { HttpModule } from '@nestjs/axios';
import { CCAService } from 'src/utils/ccaService';
import { BoomiService } from 'src/utils/BoomiService';
import { BookingModule } from 'src/booking/booking.module';
import { CronjobsModule } from 'src/cronjobs/cronjobs.module';
@Module({
controllers: [OpenApiController],
providers: [OpenApiService,CCAService,BoomiService],
imports: [HttpModule,BookingModule,CronjobsModule],
})
export class OpenApiModule {}
Это файл модуля, для которого я получаю сообщение об ошибке
import { Module } from '@nestjs/common';
import { CronjobsService } from './cronjobs.service';
import { HttpModule } from '@nestjs/axios';
import { NotificationModule } from 'src/notification/notification.module';
import { MaintenanceService } from 'src/maintenance/maintenance.service';
import { OpenApiService } from 'src/open-api/open-api.service';
import { CCAService } from 'src/utils/ccaService';
import { BoomiService } from 'src/utils/BoomiService';
import { BookingModule } from 'src/booking/booking.module';
@Module({
imports:[HttpModule, NotificationModule,BookingModule],
providers: [CronjobsService, MaintenanceService,OpenApiService,CCAService,BoomiService]
})
export class CronjobsModule {}
Я новичок в NestJs и не могу разобраться в проблеме. кто-нибудь еще сталкивался с тем же? Пожалуйста, подскажите решение.
Спасибо
Это потому, что у вас есть циклическая зависимость. Это означает, что модуль импортируется\вводится в цикле.
В твоем случае:
OpenApiService
вы импортируете «BoomiService».BoomiService
вы импортируете OpenApiService
.Всякий раз, когда инициализируется среда выполнения OpenApiService
, она вызывает Boomi, затем Boomi вызывает openAi и так далее.
Циклическая зависимость обычно является ошибкой архитектурного решения с вашей стороны.
Я заметил, что в вашем openAiService вы используете только один метод из BoomiService.
boomiResponse = await this.BoomiService.createMaintainenceRequest(PayloadForBoomi)
Было бы проще извлечь это и переместить куда-нибудь еще. Но также комментарий к этой строке и удаление импорта бумисервиса в вашем openaiService должны устранить ошибку и запустить ваш гнездовой проект. Это просто для подтверждения концепции.
Что следует сделать, так это, возможно, создать третий сервис, который импортирует как Boomi
, так и OpenAi
, и там создать функцию, которая вызывает то, что вы хотите, и когда выдаются ошибки, регистрируйте их.
Это также сделает ваш код чище и упростит его выполнение вместо связывания асинхронных функций и использования результатов в .then()
.
Это также обсуждается в документации NestJs.
Вы правы, я исправил это, удалив циклическую зависимость. В моем BoomiService
я удалил импорт OpenApiService
и переместил его код оттуда в сам OpenApiService
. это решило мою проблему. Спасибо за Ваш ответ
похоже, у вас какая-то циклическая зависимость. Прочтите страницу часто задаваемых вопросов на сайте документацииnesjs.