Marco Di Loreto
Marco Di Loreto

Reputation: 33

Is there a way of validating/parsing an optional @Query() Param into an array of Enums?

I'm trying to code a getAll() method for an Api. This method takes in a ton of different @Query() optional params as to build a filters object, and one of them is an array of enums.

like so:

enum Week{
MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY
SUNDAY
}

@Controller('activity')
export class ActivityController {

    constructor(private readonly service: ActivityService) { }

    @Get('/')
    getAllActivities(
        //many other @Query('') param
        @Query('weekDays') weekDays?: Week[],
    ) {
        //build filters object here
        // const filters = {foo}
        return this.service.getAllActivities(filters)
    }

Is there a way of parsing this using validationPipes? or any other Nest.js resource that might be unknown to me?

So far i haven't been able to use the pipes either way, it appears pipes don't really work with optional params since they throw an error if a value isn't provided.

Maybe i should just set weekDays to string, make a weekDaysParse() function and parse inside controller logic. Would that be a good practice?

Upvotes: 1

Views: 861

Answers (1)

tenshi
tenshi

Reputation: 26324

Yes, you can, with pipes.

You might implement the ParseWeekdayPipe like this:

import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';

@Injectable()
export class ParseWeekDaysPipe implements PipeTransform<any, Week[]> {
  transform(value: any, metadata: ArgumentMetadata) {
    // import Week into this file
    if (typeof value !== "string") throw new BadRequestException(`${String(value)} is not a string.`);

    const weekdays = value.split(",");

    if (weekdays.some((w) => !(w in Week))) throw new BadRequestException("Not a weekday.");

    return weekdays.map((w) => Week[w as keyof typeof Week]) // look up enum value based on member name.
  }
}

However, like you said, pipes don't really work when the param is optional, so you could also use a default value pipe:

        @Query('weekDays', new DefaultValuePipe(""), ParseWeekDaysPipe) weekDays?: Week[],

We give it an empty string instead of an empty array because ParseWeekDaysPipe will transform it into an array for us.

Upvotes: 2

Related Questions