【问题标题】:How to pass default parameters to the @Query class in Nest.Js?如何将默认参数传递给 Nest.Js 中的 @Query 类?
【发布时间】:2022-03-08 18:22:13
【问题描述】:

我正在尝试通过 Nest.Js 中的 @Query 参数将默认参数 maxnodes=3addstats=false 传递给控制器​​。

代码工作正常,但没有使用默认参数。当我传递查询参数时,会显示传递的参数,但如果没有传递,则不使用默认值(3false)。

如何解决?

context.contructor.ts:

import { CreateContextQuery } from './context.query';
import { CreateContextDto } from './context.dto';

@Post('graph')
  public async createGraphForContext(
    @Body('context') contextData: CreateContextDto,
    @Query()
    contextQuery: CreateContextQuery,
  ) {
    const before = Date.now();

    const { context } = await this.contextService.createContext(contextData);

    const graph = await this.contextService.getGraphOfContext(
      context.id,
      contextQuery.maxnodes,
      contextQuery.addstats,
    );

}

context.query.ts:

import { ApiProperty } from '@nestjs/swagger';

export class CreateContextQuery {
  @ApiProperty({
    description: 'Maximum number of nodes to show on the graph',
  })
  maxnodes;
  @ApiProperty({
    description: 'Include graph statistics',
  })
  addstats;
  constructor(maxnodes = 3, addstats = false) {
    this.maxnodes = maxnodes;
    this.addstats = addstats;
  }
}

【问题讨论】:

    标签: node.js typescript nestjs


    【解决方案1】:

    您在查询参数中收到的是一个普通对象。您可以在查询参数中放置一个管道并应用类转换来实例化该类。

    【讨论】:

      【解决方案2】:

      阅读:https://docs.nestjs.com/pipes#providing-defaults

      contextQuery 不是CreateContextQuery 的实例,因为在没有任何配置的情况下,Nest 不会在任何时候调用new CreateContextQuery。这就是你最终使用管道的原因(阅读此https://docs.nestjs.com/techniques/validation#transform-payload-objects

      【讨论】:

        【解决方案3】:

        所以基本上在你的 DTO 中,你可以给出默认值。

        export class CreateContextQuery {
          @IsOptional()
          @Type(() => Number)
          @IsNumber()
          @Min(0)
          maxnodes?: number = 3;
        
          @IsOptional()
          @Type(() => Boolean)
          @IsBoolean()
          addstats?: boolean = false;
        
          constructor(maxnodes = 3, addstats = false) {
            this.maxnodes = maxnodes;
            this.addstats = addstats;
          }
        }
        // as you can see i am using validation too
        
        

        在你的控制器中:

          @Post('graph')
          @UsePipes(new ValidationPipe({ transform: true })) 
        // you need to add this for tansformation
          public async createGraphForContext(
            @Body('context') contextData: CreateContextDto,
            @Query()
            contextQuery: CreateContextQuery,
          ) {
            const before = Date.now();
        
            const { context } = await this.contextService.createContext(contextData);
        
            const graph = await this.contextService.getGraphOfContext(
              context.id,
              contextQuery.maxnodes,
              contextQuery.addstats,
            );
        
        }
        
        

        PS

        此外,如果您愿意,您可以添加自定义装饰器,在您的情况下: // 添加这个装饰器

        export const GetContextQuery = createParamDecorator((_data: unknown, ctx: ExecutionContext): CreateContextDto => {
          const request = ctx.switchToHttp().getRequest();
          const query = request.query;
        
          const maxnodes = parseInt(query.maxnodes) || 3;//default values here in case it fails to parse
          const addstats = Boolean(query.addstats) || 0;
          return { addstats, addstats };
        });
        

        在你的控制器中,你可以调用装饰器而不是@Query 只需添加你的装饰器@GetContextQuery() context: CreateContextDto,现在你不需要 UsePipes

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-02-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多