It would be nice if we could have conditional decorator for required/non-required properties.
Example use case:
I want to insert or update a record.
When inserting a new row the title is required, but when updating the releaseYear on existing row the title column is not required.
I could get around this by creating two different classes InsertRecordParameters and UpdateRecordParamaeters but it would be nice to have eveything in one class when insert and update do not differ in terms of the parameters used.
class SaveRecordParameters {
@IsOptional()
@IsPositive()
id?: number;
@IsOptionaIf( self => !!self.id )
@MaxLength(5)
@MinLength(50)
title?: string;
@IsOptional()
@IsNumber()
releaseYear?: number;
}
@ibox4real you can use Validation groups. They are meant exactly for what you are looking for.
Example class:
A class that I used in a project here
export enum RecordParametersValidationGroup {
CREATION = 'creation',
UPDATE = 'update',
};
export defaul class SaveRecordParameters {
@IsOptional()
@IsPositive()
id?: number;
@Length(5, 50, { groups: [RecordParametersValidationGroup.UPDATE] }])
title?: string;
@IsOptional({ groups: [RecordParametersValidationGroup.UPDATE] })
@IsNumber()
releaseYear?: number;
}
Example usage:
The usage here
import {validate} from "class-validator";
import { RecordParametersValidationGroup } from '@entity/SaveRecordParameters ';
// ...
validate(an_example_instance_of_record_parameters, {
groups: [RecordParametersValidationGroup.UPDATE]
});
There's a pull request for a conditional @IsOptional decorator here: https://github.com/typestack/class-validator/pull/196
But it hasn't been merged in over two years now.
Looks way simpler when you have an IsOptionalIf
You can achieve this by creating your own decorator that wraps @ValidateIf.
/**
* Mark the property as optional if the function returns truthy
*
* @param optionalIfPropertyIsSet
*/
function IsOptionalIf(allowOptional: (obj: any, value: any) => boolean, options?: ValidationOptions) {
// If required, do validate. Otherwise if null|undefined, don't validate
return ValidateIf((obj, value) => !allowOptional(obj, value) || value != null), options)
}
class SaveRecordParameters {
@IsOptional()
@IsPositive()
id?: number;
@IsOptionalIf(self => !!self.id)
@MaxLength(5)
@MinLength(50)
title?: string;
@IsOptional()
@IsNumber()
releaseYear?: number;
}