I have this:
import * as val from 'class-validator';
import {ObjectId as MongoId} from 'mongodb';
@val.ValidatorConstraint({async: false})
export class IsTraceValidConstraint implements val.ValidatorConstraintInterface {
validate(trace: any, args: val.ValidationArguments) {
return trace.deviceId && typeof trace.deviceId === 'string'; // << trace is undefined
}
defaultMessage(args: val.ValidationArguments) {
return 'Trace validation failed';
}
}
// Function to create the class-level decorator
export function IsTraceValid(validationOptions?: val.ValidationOptions) {
return function (target: Function) {
val.registerDecorator({
target: target,
options: validationOptions,
constraints: [],
validator: IsTraceValidConstraint,
name: 'isTraceValid',
propertyName: 'isTraceValid',
});
};
}
then I use it like so:
@IsTraceValid()
@t.Unique("user-hash-device", ["hash", "userId", "deviceId"])
@t.Entity('vibe_trace')
export class Trace extends From<Trace> { }
but if I run it, I get a null pointer -
trace is undefined in validate callback - so
trace.deviceId
throws an error
Clearly I am doing something wrong - but what?
Update propertyName
in your decorator registration to match the name of the property you want to validate in your custom constraint. i.e. 'deviceId'
.
In your custom constraint you now check directly against that value in your validate
method. If you want to check against other properties you can access the trace instance via args.object
import * as val from 'class-validator';
import { ObjectId as MongoId } from 'mongodb';
@val.ValidatorConstraint({ async: false })
export class IsTraceValidConstraint implements val.ValidatorConstraintInterface {
validate(value: any, args: val.ValidationArguments) {
// trace instance is accessible via `args.object`
return typeof value === 'string';
}
defaultMessage(args: val.ValidationArguments) {
return 'Trace validation failed';
}
}
// Function to create the class-level decorator
export function IsTraceValid(validationOptions?: val.ValidationOptions) {
return function (target: Function) {
val.registerDecorator({
target: target,
options: validationOptions,
constraints: [],
validator: IsTraceValidConstraint,
name: 'isTraceValid',
propertyName: 'deviceId',
});
};
}