Skip to content

feat: allow casting strings to boolean #626

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
QuanticPotatoes opened this issue Mar 4, 2021 · 11 comments · May be fixed by #1686 or #1776
Closed

feat: allow casting strings to boolean #626

QuanticPotatoes opened this issue Mar 4, 2021 · 11 comments · May be fixed by #1686 or #1776
Labels
status: duplicate Issue is being tracked already in another issue. type: feature Issues related to new features.

Comments

@QuanticPotatoes
Copy link

QuanticPotatoes commented Mar 4, 2021

Hi, I use class-transformer on NestJS and a cast problem occured during the conversion of the request payload.

Example :

{
"page": "1",
"limit": "1",
"isAnnotate": "false"
}

We got :

{
page: 1,
limit: 1,
isAnnotate: true
}

The defining class is :

class ArticleQuery {
  page: number;

  limit: number;

  isAnnotate?: boolean
}

https://github.com/nestjs/nest/blob/master/packages/common/pipes/validation.pipe.ts#L96
When the plainToClass function was executed such as :

/*
* metatype => ArticleQuery
* value => { page: "1", limit: "1",  isAnnotate: "false" }
* transformOptions => { enableImplicitConversion: true }
* /
classTransformer.plainToClass(metatype, value, this.transformOptions);

After a little digging, i found the caused into the function transform :
https://github.com/typestack/class-transformer/blob/develop/src/TransformOperationExecutor.ts#L108

    } else if (targetType === Boolean && !isMap) {
      if (value === null || value === undefined) return value;
      return Boolean(value);

So i made a patch locally to solve the issue :

    } else if (targetType === Boolean && !isMap) {
      if (value === null || value === undefined) return value;
      return value === "true";

Is it an attended behavior from the function to not convert a string "true"/"false" to a Boolean ?

Current version: 0.4.0

Best regards

@QuanticPotatoes QuanticPotatoes added status: needs triage Issues which needs to be reproduced to be verified report. type: fix Issues describing a broken feature. labels Mar 4, 2021
@tferi99
Copy link

tferi99 commented Mar 12, 2021

@QuanticPotatoes - will this fix be committed into next official version?

@skrosoft
Copy link

skrosoft commented Mar 23, 2021

"false" is true ... In my opinion, this should not be casted, correct type or transform annotation should be used.

@Transform(({ obj }) => {
    return [true, 'enabled', 'true'].indexOf(obj.isAnnotate) > -1;
})

@felinto-dev
Copy link

felinto-dev commented Mar 28, 2021

"false" is true ... In my opinion, this should not be casted, correct type or transform annotation should be used.

@Transform(({ obj }) => {
    return [true, 'enabled', 'true'].indexOf(obj.isAnnotate) > -1;
})

Good Job!

I was looking for it! Is there any way to return an error if no "true" or "false" was sent?
I think to accept any value (that not be true) as false is weird.

Other way could be use with class-validator:

  @Transform(({ value }) => {
    return [true, 'enabled', 'true'].indexOf(value) > -1;
  })
  @IsBooleanString()
  isUnlocked: boolean;

but just does not work for me and I don't have any idea about what is happening
When I use it with "IsBooleanString" decorator, I just receive, 400 bad request that says "isUnlocked must be a boolean string".

I would throw a 400 BAD REQUEST exception error if no "true" or "false" was sent.

@jacobdo2
Copy link

"false" is true ... In my opinion, this should not be casted, correct type or transform annotation should be used.

@Transform(({ obj }) => {
    return [true, 'enabled', 'true'].indexOf(obj.isAnnotate) > -1;
})

Your statement is "false"

@popovmi
Copy link

popovmi commented Oct 5, 2021

@Transform(({ value }) => {
return [true, 'enabled', 'true'].indexOf(value) > -1;
})
@IsBooleanString()

After transforming value is boolean, not boolean-string. That's why u get error. Either make @isboolean() or remove @Transform()

@zachzhao1984
Copy link

I just want undefined not to be tranformed to false actually

@andrebrito
Copy link

andrebrito commented May 12, 2022

Hey, guys.
I'm in a similar place. Using @joanna-liana's answer, I've manage to work around like this:

// dto
@IsOptional()
@IsBoolean()
@Transform(({ value }) => {
  if (value === 'true') return true;
  if (value === 'false') return false;
  return value;
})
private: boolean;
// controller
@UsePipes(
  new ValidationPipe({
    always: true,
  }),
)

It's fishy, but it works.

@zaptree
Copy link

zaptree commented Aug 24, 2023

I think a good argument for why 'false' should be treated as false is that class transformer gets used for parsing using requests and if the request is a GET and not a post all values get converted into strings thus false becomes 'false'. I'm having this trouble when using nestjs and doing GET requests. I use the qs lib to convert my request object qs.stringify(requestObject) which in the end my 'false' becomes true.

@dexat0r
Copy link

dexat0r commented Apr 18, 2024

For me worked IsBooleanString decorator:

DTO:

@IsBooleanString()
@IsOptional()
isEnabled?: boolean

Controller:

@Get("/")
public async getEnabled(@Query(new ValidationPipe({ transform: true })) query: DTO) { ... }

@NoNameProvided NoNameProvided added type: feature Issues related to new features. status: duplicate Issue is being tracked already in another issue. and removed type: fix Issues describing a broken feature. status: needs triage Issues which needs to be reproduced to be verified report. labels May 4, 2024
@NoNameProvided
Copy link
Member

Duplicate of #550.

@NoNameProvided NoNameProvided closed this as not planned Won't fix, can't repro, duplicate, stale May 4, 2024
@NoNameProvided NoNameProvided changed the title fix: Cast string to Boolean feat: allow casting strings to boolean May 4, 2024
Copy link

github-actions bot commented Jun 4, 2024

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 4, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
status: duplicate Issue is being tracked already in another issue. type: feature Issues related to new features.