I'm creating a Custom Decorator to use in some routes of my service. It basically validates an one time password parameter. The problem is the method that validates this is in another class and i just want to use it
Here is my code for the Decorator:
import { OtpClient } from '../../otp/otp.client';
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
export const validateOtpDecorator = createParamDecorator(
async (data: unknown, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();
const {otp} = request.body;
//Here i need to inject the OtpClient.
const validationResult = await otpClient.validateOtp(otp);
return validationResult;
},
);
I tried to use something like this but it didn´t work:
const moduleRef = ctx.getArgByIndex(3);
const otpClient = moduleRef.get(OTP_CLIENT_ADAPTER);
here is the code of the OtpClient Class:
export class OtpClient implements OtpClientAdapter {
private readonly formatMessage = new BusinessDataMessage(OtpClient.name);
constructor(
@Inject(LOGGER_ADAPTER) private readonly logger: LoggerAdapter,
@Inject(HTTP_INTERCEPTOR) private readonly httpInterceptor: HttpInterceptor,
) {}
async validateOtp(
otp: string,
): Promise<ValidateOtpTokenResponseDTO> {
//some logic here to call another api to get if the otp is valid
} catch (error) {
const err = error as AxiosError;
const message = this._isCriticalError(err) ? 'Critical error' : 'Failed to validate otp';
this.logger.error(this.formatMessage.generic(methodName, message), { err });
throw this._handleError(error);
}
}
}
I'm new to nestjs and i'm really stuck in this situation and wanted some help =)
I would argue this should be done in a pipe rather than a decorator. Nest's parameter decorators are meant to be lightweight and should not be used to try and make use of the DI system, as they are not designed for that. If you need injected classes or asynchronous processing, a pipe should be used instead.