5

I have a schema with an enum:

export interface IGameMapModel extends IGameMap, Document {}

export const gameMapSchema: Schema = new Schema({
  name: { type: String, index: { unique: true }, required: true },
  type: { type: String, enum: CUtility.enumToArray(GameMode) }
});

export const GameMap: Model<IGameMapModel> = model<IGameMapModel>('GameMap', gameMapSchema);

The GameMap is an enum.

First problem is already in here: I need to convert the enum to a string array in order to use it with the schema.

Secondly, I wanna use an enum value directly during the schema creation.

new GameMap({
  name: 'Test',
  type: GameMode.ASSAULT
});

returns ValidationError: type: '1' is not a valid enum value for path 'type'.

I am not sure whether this can actually work due to the string array I set in the model enum property.

My idea would be to create some kind of type conversion during the schema creation. Does this work with mongoose or would I have to create some kind of helper for object creation?

2 Answers 2

6

GameMode.ASSAULT is evaluating as it's numeric value, but GameMode is expecting the type to be a string. What are you expecting the string evaluation to be? If you need the string value of the enum, you can access it with GameMode[GameMode.ASSAULT], which would return ASSAULT as a string.

For example:

enum TEST {
    test1 = 1,
    test2 = 2
}

console.log(TEST[TEST.test1]);
//Prints "test1"

From the Mongoose docs on validation, in schema properties with a type of String that have enum validation, the enum that mongoose expects in an array of strings.

This means that CUtility.enumToArray(GameMode) needs to either return to you an array of the indexes as strings, or an array of the text/string values of the enum--whichever you are expecting to store in your DB.

The validation error seems to imply that 1 is not contained within the array that is being produced by CUtility.enumToArray(GameMode), or the validation is seeing GameMode.ASSAULT as a number when it is expected a string representation of 1. You might have to convert the enum value you are passing in into a string.

What is the output of CUtility.enumToArray(GameMode)? That should help you determine which of the two is your problem.

Sign up to request clarification or add additional context in comments.

5 Comments

My last sentence includes my question, I'd appreciate it if you could read my question and maybe update your answer.
Again, what are you expecting the "type" parameter to be? Example?
Due to the schema, it must be a string. And my question is if there is a possible supply the enum and it gets converted by mongoose or some function I create.
Kinda, yeah. CUtility.enumToArray(GameMode) returns ['ASSAULT','MORE']. Know why the TypeError is returned, but I wonder if there is a way to create an object using new Test({type: GameMode.ASSAULT})and mongoose or another helper method turns this into a string so I don't have to use GameMode[GM.Assault] each time.
I think you'll probably just have to create your own helper method, but that's probably not going to save you much code by abstracting it.
3

Why don't you just create custom getter/setter:

const schema = new Schema ({
    enumProp: {
            type: Schema.Types.String,
            enum: enumKeys(EnumType),
            get: (enumValue: string) => EnumType[enumValue as keyof typeof EnumType],
            set: (enumValue: EnumType) => EnumType[enumValue],
        },
});

EDIT: Don't forget to explicitly enable the getter

schema.set('toJSON', { getters: true }); 
// and/or
schema.set('toObject', { getters: true });

This way you can fine-control how exactly you want to represent the prop in the db, backend and frontend (json response).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.