#javascript #express #nestjs #typeorm #class-validator
#javascript #выразить #nestjs #typeorm #класс-валидатор
Вопрос:
Я пытаюсь проверить массив идентификаторов, для проверки я использую пользовательский валидатор в проекте nestjs. Я передаю массив идентификаторов в функции обратного вызова своему классу обслуживания для запроса из базы данных, существует ли идентификатор в таблице или нет, и возвращает логическое значение. Каждый раз, когда я получаю логическое значение true, даже если я передаю неправильный идентификатор.
Вот функция проверки в пользовательском валидаторе
import { ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments, registerDecorator, ValidationOptions } from "class-validator";
import { DeviceService } from "../device/device.service";
import { Injectable } from "@nestjs/common";
@ValidatorConstraint({ async: true })
@Injectable()
export class DevicesArrayValidatorConstraint implements ValidatorConstraintInterface {
constructor(private deviceService: DeviceService) { }
async validate(devices: Array<number>, args: ValidationArguments) {
let result = devices.every(async (deviceId) => await this.deviceService.validateDevice(deviceId));
if(result){
return true;
}
else{
return false;
}
}
defaultMessage(args: ValidationArguments) { // here you can provide default error message if validation failed
return "Here is an error";
}
}
export function ValidDevices(validationOptions?: ValidationOptions) {
return function (object: Object, propertyName: string) {
registerDecorator({
target: object.constructor,
propertyName: propertyName,
options: validationOptions,
validator: DevicesArrayValidatorConstraint
});
};
}
Это функция из класса обслуживания
async validateDevice(deviceId: number) {
try {
let result = await this.deviceRepository.findOneOrFail(deviceId)
if(result){
console.log(`In try block,This is id ${ deviceId}`)
}
} catch (error) {
return false;
}
return true;
}
Если я передаю массив devices: [1,4]
, где 1 является допустимым, а 4 недопустимым. Я получаю двойной логический результат, если я console.log()
возвращаю значение.
прикрепление сообщения консоли
Комментарии:
1.
every
не понимает асинхронные функции. Он просто видит обещание, которое возвращается как истинное значение.2. что может быть обходным путем?
3.
if(result) { return true; } else { return false; }
—result
уже является логическим значением, поэтому вы можете простоreturn result
4. Тоже так делал, но всегда получал логическое значение true;
Ответ №1:
every
не понимает асинхронные функции. Он просто видит обещание, которое возвращается как истинное значение.
У вас есть несколько вариантов:
Если вы хотите проверить все устройства параллельно, проверьте результат:
const validityFlags = await Promise.all(devices.map(deviceId => this.deviceService.validateDevice(deviceId)));
let result = validityFlags.every(Boolean);
Или, если вы хотите проверять каждое устройство последовательно, не беспокоясь о более поздних, если вы знаете, что более раннее недопустимо:
let result = true;
for (const deviceId of devices) {
const valid = await this.deviceService.validateDevice(deviceId);
if (!valid) {
result = false;
break;
}
}
Комментарии:
1. (Дох! Опечатка. Если вы видите
for-in
цикл выше, нажмите обновить. Это должен бытьfor-of
цикл.)2. @Andreas — ЛОЛ, довольно. Итак, две опечатки. 🙂 Спасибо!!
3. Та же проблема, если я проверяю все устройства параллельно.
4. и если я проверяю каждое устройство, я не могу использовать break, потому что мне нужно логическое значение, которое break не позволяет передавать;
5. @Hareemrehan Вы можете заменить тело своей
async validate(...) { ... }
функции одной из двух версий из этого ответа, и она должна работать. «Я не могу использовать break, потому что мне нужно логическое значение» — отсюдаresult
и переменная.