NestJS - Validating body conditionally, based on one property
Solution 1
Have you tried using groups? Instead of having multiple DTOs, you just create one DTO. Every property is assigned to one or multiple groups:
@Min(12, {groups: ['registration', 'update']})
age: number;
@Length(2, 20, {groups: ['registration']})
name: string;
You can then conditionally pass the groups to class transformer / validator:
@Injectable()
export class ConditionalValidationPipe implements PipeTransform {
async transform(entity: any, metadata: ArgumentMetadata) {
// Dynamically determine the groups
const groups = [];
if (entity.selectedCategory === 1) {
groups.push('registration');
}
// Transform to class with groups
const entityClass = plainToClass(EntityDto, entity, { groups })
// Validate with groups
const errors = await validate(entityClass, { groups });
if (errors.length > 0) {
throw this.createError(errors);
}
return entityClass;
}
}
Solution 2
Have you tried the ValidateIf statement?
You can have multiple validations for props1
or props2
and apply them if selectedCategory
is "category 1" or "category 2" accordingly.
Related videos on Youtube
maxime1992
As a web developer, I like to be versatile : Design or participate in the overall UI, work on backend (mostly REST API) and what I prefer is the frontend. Indeed, designing good Single Page Application is a real challenge and I like to start from the user's requirements, then design the architecture and move the project into production. I'm currently playing a lot with Angular2 and the platform is really good. What I really enjoy about this is that we can leverage the power of Angular2 by using some powerful pattern (observable and immutable) to improve the code and the performances. If you want to know more about some projects I've been working on, I invite you to take a look at my Github & Gitlab accounts : Github : https://github.com/maxime1992 Gitlab : https://gitlab.com/u/maxime1992 You can also follow me on Twitter.
Updated on June 04, 2022Comments
-
maxime1992 almost 2 years
I'm trying to find a nice way to validate a body using DTO (using the brilliant
class-validator
andclass-transformer
libraries). It works really well, even for nested structures but in my case I'd like to have the body property based on some conditions.Example that will probably help to understand:
Let's imagine my body should always have
selectedCategory
. Based on that field, the content could either be from category 1, which containsprop1
OR from category 2, which containsprop2
.I do not want to allow a null for both of them, I really want to have to either have
prop1
defined orprop2
based on theselectedCategory
.I think that I could use a pipe, but then how can I specify the correct DTO to use?
I've built a "base" class with all the common properties and few other classes that inherit from it.
I could instantiate the pipe manually based on the property
selectedCategory
, that'd be ideal but I have no clue what to pass as a second argument of the pipe (metadata).Thanks for your help.
-
Eddie Monge Jr over 3 yearswhere do you have
this.createError
defined? -
Kim Kern over 3 years@EddieMongeJr Wherever you want to define your custom error handling, e.g., directly in the pipe. Also, have a look at the validation errors: github.com/typestack/class-validator#validation-errors
-
Blackfaded over 3 yearsDou you have an example on how tonuse that pipe in a controller?
-
Kim Kern over 3 years@Blackfaded Have a look at the binding pipes docs: docs.nestjs.com/pipes#binding-pipes
-
Juan Rojas about 3 yearsDid anyone tried a FluentValidation style? like: fluentvalidation-ts.alexpotter.dev/docs/overview.html