#How to inject repo to Custom validation?

9 messages · Page 1 of 1 (latest)

steel mango
#
import { InjectRepository } from "@nestjs/typeorm";
import { ValidatorConstraint, ValidatorConstraintInterface } from "class-validator";
import { Customer } from "../entities/customer.entity";
import { Repository } from "typeorm";

@ValidatorConstraint({ async: true })
export class CustomerPhoneExistsRule implements ValidatorConstraintInterface {
    constructor(@InjectRepository(Customer) private customerRepo: Repository<Customer>) {}

    async validate(customerPhone: string) {
        console.log(customerPhone);

        console.log(await this.customerRepo.find({ where: { isActive: true } }));

        return this.customerRepo
            .findOneBy({ phone: customerPhone, isActive: false, deletedAt: null })
            .then(customer => {
                return customer !== undefined;
            });
    }

    defaultMessage(): string {
        return "Customer phone number already exists";
    }
}

I was tryna add a custom validation to my project, but i keep getting an error saying
TypeError: Cannot read properties of undefined (reading 'find').

when i googled i saw many people using the repository pattern with separate repository file and injecting that to the validation. is that the only way it'll work ?

left pulsar
#

Did you add the useContainer method to the main.ts

steel mango
#

i didn't add it at first, now i've added it and tried, same error showing.

left pulsar
#

Can you show the main.ts

steel mango
#
async function bootstrap() {
    const app = await NestFactory.create<NestExpressApplication>(AppModule);

    const configService = app.get(ConfigService<IConfig, true>);

    const logger = new Logger("Bootstrap");

    // =====================================================
    // configureNestGlobals
    // =====================================================

    const globalPrefix = configService.get("app.prefix", { infer: true });

    app.setGlobalPrefix(globalPrefix);

    app.useGlobalPipes(
        new ValidationPipe({
            whitelist: true,
            transform: true,
            forbidUnknownValues: false,
        }),
    );

    // =========================================================
    // configureNestSwagger
    // =========================================================

    AppUtils.setupSwagger(app, configService);

    // ======================================================
    // security
    // ======================================================

    app.use(compression());
    app.enable("trust proxy");
    app.set("etag", "strong");
    app.use(bodyParser.json({ limit: "10mb" }));
    app.use(bodyParser.urlencoded({ limit: "10mb", extended: true }));
    app.use(helmet());
    app.enableCors({
        methods: "GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS",
        maxAge: 3600,
        origin: configService.get("app.allowedHosts", { infer: true }),
    });

    const port = process.env.PORT || configService.get("app.port", { infer: true });

    useContainer(app.select(AppModule), { fallbackOnErrors: true });
    await app.listen(port);

    logger.debug(`🚀 Application is running on: http://localhost:${port}/${globalPrefix}`);

    logger.debug(`📑 Swagger is running on: http://localhost:${port}/doc`);
}
(async () => await bootstrap())();
left pulsar
#

Hmm, and the validator is added to a providers array, right?

steel mango
#

@left pulsar I think i fixed it...

@Module({
    imports: [TypeOrmModule.forFeature([Customer])],
    controllers: [CustomerController],
    providers: [CustomerService, CustomerPhoneExistsRule],
})
export class CustomerModule {}

added my custom validation CustomerPhoneExistsRule as the module's provider.

steel mango
#

@left pulsar Thanks mate.