My "AppState" enum has following possible enum values:
export enum AppState {
SUCCESS,
ERROR,
RUNNING
}
I have a UpdateAppStateDTO with an appState
which should accept every enum value except RUNNING.
export class UpdateAppStateDTO {
@IsEnum(AppState)
@NotEquals(AppState.RUNNING) // Doesn't work properly
public appState: AppState;
}
For the route I have this example
@Patch()
public setState(@Body() { appState }: UpdateAppStateDTO): void {
console.log(appState);
}
If the request has an empty body or a non valid enum value like "foobar" for appState
I'm getting a 400, which is fine.
The problem is that when I send "RUNNING" I'm still getting a 200 instead of a 400.
How can I prevent this behaviour?
I assume you are sending in the string 'RUNNING'
, and you're trying to make sure that that is what is not used, correct? With what you've currently got, your enum maps to these values:
export enum AppState {
SUCCESS = 0,
ERROR = 1,
RUNNING = 2
}
So if you send in the string 'RUNNING'
, the validator checks that RUNNING !== 2
which is in fact true
leading to successful validation. The @IsEnum()
decorator checks that the value sent in in a valid key of the enum, so sending in 'RUNNING'
passes that check, hence why you don't get some sort of error there.
The most verbose way to fix this is to make your enum a string enum
like so:
export enum AppState {
SUCCESS = 'SUCCESS',
ERROR = 'ERROR',
RUNNING = 'RUNNING'
}
This will make each AppState
value map to its corresponding string, though that does lead to having to type out a lot of declarations and can lead to duplicate code.
Another way to manage this is to set your @NotEquals()
enum to the key provided by the enum value like so:
export class UpdateAppStateDTO {
@IsEnum(AppState)
@NotEquals(AppState[AppState.RUNNING])
public appState: AppState;
}
But keep in mind that with this approach when you look at appState
later it will still be a numeric value instead of a string.
You can play around with this stackblitz I made for this to see some running code.