Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to set default values for a DTO?

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 ?

like image 631
papillon Avatar asked Apr 02 '19 15:04

papillon


People also ask

Can you set default value DTO?

You can set default values in the service and the function that uses the data like the example below if it is the case for you. If you don't pass any value to the function the default values will be set.

How do you assign default values to variables?

The OR Assignment (||=) Operator The logical OR assignment ( ||= ) operator assigns the new values only if the left operand is falsy. Below is an example of using ||= on a variable holding undefined . Next is an example of assigning a new value on a variable containing an empty string.

What is DTO Nestjs?

A DTO is an object that defines how the data will be sent over the network. We could determine the DTO schema by using TypeScript interfaces, or by simple classes. Interestingly, we recommend using classes here.


1 Answers

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);
like image 182
Kim Kern Avatar answered Oct 13 '22 08:10

Kim Kern