routing-controllers
routing-controllers copied to clipboard
fix: Enum in @QueryParams and @QueryParam: Value cannot be parsed into JSON
Some code to reproduce issue:
enum LabelType {
Sent = 'Sent',
Inbox = 'Inbox'
}
class Query {
@IsEnum(LabelType)
label: LabelType;
}
@JsonController()
export class ThreadController {
@Get('/threads')
async list(
@QueryParams() query: Query
) {
return "ok";
}
@Get('/threads/one')
async list(
@QueryParam('label') label: LabelType,
) {
return "ok";
}
@Post('/threads')
async postList(
@Body() query: Query
) {
return "ok";
}
}
Issue:
Post method is working as expected, but Get fails with this error:
Http error: Given parameter label is invalid. Value ("Sent") cannot be parsed into JSON.
Possible reason:
Typescript emits "Object" for "design:type" when type is inferred original issue. In that case string enum treats as an object and routing-controllers tries to parse string.
That happens in normalizeParamValue
method of ActionParameterHandler
here. normalizeParamValue
isn't handles params from @Body
, that's why Post works as expected.
Workaround:
Until it fixed we can explicitly specify enum type. Not sure if that will not break anything else, but working fine for me:
export class Query {
@Reflect.metadata('design:type', { name: 'string' })
@IsEnum(LabelType)
label: LabelType;
}
For @QueryParam
it's possible to set parameter's type:
@QueryParam('label', { type: 'string' }) label: LabelType
Unable to reproduce issue with @QueryParams
on test project with no extra dependencies, but still reproducable in work project.
For @QueryParam
reproducing everywhere, tried
routing-controllers 0.7.7 and 0.8.0
typescript 3.7.2 and 3.7.4
Test repo: https://github.com/DimaIT/routing-controllers-enum-issue
Issue is reproducable only with --transpile-only
flag for ts-node
.
Works as expected without it or with compiled files.
Im getting a the same error with union types (string | string[]
) or type any
. I must pass double quotes (?search="foo"
) for a single param to work. Im using [email protected], [email protected] [email protected] Here is an example repo
I confirm the bug exists on "routing-controllers": "^0.9.0-alpha.2",
Possible workaround:
@Get('/:id')
public async get(
@CurrentUser() currentUser: User,
@Req() req: any,
// @Param('id') id: number | string,
) {
// console.log(req);
const id = req.params.id;
const item = await this.localManager.findByUserAndReferenceId(currentUser, id);
return item.getBody();
}
same problem
same problem here!
@gtbl2012 @exejutable been working on similar https://github.com/typestack/routing-controllers/issues/703 and have PR waiting to be merged https://github.com/typestack/routing-controllers/issues/703 Once it will be merged, it would be great if you could test the changes made on your side.
same problem version "0.9.0"
same problem here
only when covering param with double-quotes, it would be parsed and work. i think it could be a parser problem
same problem
I cant send something like comment/b481d670
from the front, unless wrap it with double quotes:
comment/"b481d670"
I had the same error : Http error: Given parameter label is invalid. Value ("state") cannot be parsed into JSON. I upgrade typescript version and that fixed the issue. old version : "typescript": "^4.5.5", new version "typescript": "4.9.5"
i tried with 4.6.2 and it works too.
Updating my TypeScript did not work.
When I build the app and run the JS application, it doesn't show any error =/ Running ts-node without transpile-only worked for me.
Also, I am using type, not enums.
@pauloendoh keep it mind types are not available during runtime!
@attilaorosz
Yeah, I use the IsIn decorator that accepts an array of values
const itemTypes = ['tvSeries', 'movie'] as const
type ItemType = typeof itemTypes[number]
class Item {
@IsIn(itemTypes)
type: ItemType
}
Anyone still having this issue? I'm trying with @IsIn
as well and it still does not work.
I still have this problem, any solutions?