Is it possible to set default values for a DTO?

23,629

You can set default directly in your DTO class:

export class MyQuery {
  readonly myQueryItem = 'mydefault';
}

You have to instantiate the class so that the default value is used. For that you can for example use the ValidationPipe with the option transform: true. If the value is set by your query params it will be overriden.

@Get()
@UsePipes(new ValidationPipe({ transform: true }))
getHello(@Query() query: MyQuery) {
  return query;
}

Why does this work?

1) Pipes are applied to all your decorators, e.g. @Body(), @Param(), @Query() and can transform the values (e.g. ParseIntPipe) or perform checks (e.g. ValidationPipe).

2) The ValidationPipe internally uses class-validator and class-transformer for validation. To be able to perform validation on your input (plain javascript objects) it first has to transform them to your annotated dto class meaning it creates an instance of your class. With the setting transform: true it will automatically create an instance of your dto class.

Example (basically how it works):

class Person {
  firstname: string;
  lastname?: string = 'May';

  constructor(person) {
    Object.assign(this, person);
  }
}

// You can use Person as a type for a plain object -> no default value
const personInput: Person = { firstname: 'Yuna' };

// When an actual instance of the class is created, it uses the default value
const personInstance: Person = new Person(personInput);
Share:
23,629
papillon
Author by

papillon

Hi :)

Updated on July 09, 2022

Comments

  • papillon
    papillon almost 2 years

    Is there some way to use default values when a query is empty?

    If I have the following DTO for a query:

    export class MyQuery {
      readonly myQueryItem: string;
    }
    

    And my request contains no query, then myQuery.myQueryItem will be undefined. How do I make it so it has a default value ?