class-transformer
class-transformer copied to clipboard
@Expose ignores default value
Description
When using @Expose with a default value, the default value is ignored
export class ExampleDTO {
@IsBoolean()
@Type(() => Boolean)
booleanValue = false;
@IsNumber()
@Min(4)
@Type(() => Number)
digits = 6;
}
This works fine and produces expected: {booleanValue: false, digits: 6}
on empty input. However:
export class ExposeExampleDTO {
@IsBoolean()
@Type(() => Boolean)
@Expose({ name: 'boolean_value' })
booleanValue = false;
@IsNumber()
@Min(4)
@Type(() => Number)
@Expose({ name: 'dgt' })
digits = 6;
}
fails validation as it produces '{}' without validation on empty input.
Expected behavior
Parameters with @Expose decorator should assume default value from the class declaration when the exposed parameter is undefined in the source.
Actual behavior
Parameters with @Expose decorator ignore default value when the exposed parameter is undefined in the source and are undefined.
have_you_solved_this_problem
@yonghui666 no, I haven't. Had to skip the validation here and validate it later in the code.
Can confirm this issue. We want to have a boolean toggle-state attribute which is not passed from outside (e.g. public active: boolean = false
). But during initialization, this attribute is always undefinded
while the other properties from outside are deserialized and set.
Hello @rostislav-kondratenko-lmnd,
You can use the exposeDefaultValues
option when calling plainToInstance
. With this option transformation will preserve the default value, when not set in plain.
For the NestJS users:
Follow the docs at https://docs.nestjs.com/techniques/validation#auto-validation to configure your app. Customize the validation pipe as demonstrated below.
export const DEFAULT_VALIDATION_PIPE_OPTIONS: ValidationPipeOptions = {
transform: true,
...
transformOptions: {
// NOTE: This is necessary to ensure default values are respected when
// using the Expose decorator from class-transformer.
exposeDefaultValues: true,
},
};
export const validationPipe = new ValidationPipe(
DEFAULT_VALIDATION_PIPE_OPTIONS
);
app.useGlobalPipes(validationPipe);
Thank you @clintonb!
Closing as answered. If you have any questions left feel free to comment on this issue.