Mongoose Model Options field - node.js

Hi I just started playing with Mongoose. It seems pretty awesome!
Now coming from a Django background, how would one implement a type of options field like:
STATUS_OPTIONS : [{"Open",1},{"Closed",2},{"Pending",3"}]
status: { type:String, required:true, options:STATUS_OPTIONS },
So that it can be set like status = Open or something like that.
Or should this just be a normal String field and I set it accordingly in my app?

You can constrain a Mongoose schema string field to a set of enumeration values with the enum attribute:
var s = new Schema({
status: { type: String, enum: ['Open', 'Closed', 'Pending'] }
});

What you may be trying to do is reference some possibilities, right? Probably like an enum field type.
Well, you may have better luck using directly an String or using another Schema (but if you only need the strings Closed, Open, Pending, this wouldn't be needed).

Related

Set mongoose field as type of either String or Number

I have a field example in my database, which I want it to be either Number or String:
export const mySch = new mongoose.Schema({
example: {
type: String,
},
});
How can I do it?
There is a type in mongoose Schema.Types.Mixed which can be used to save values of any type in the given field. However, I haven't yet found a way to restrict it to just a particular subset of types e.g String and Number.
Here is the link if you want to study in detail yourself: https://mongoosejs.com/docs/schematypes.html#mixed.
You can use Mongoose Discriminator.
https://mongoosejs.com/docs/discriminators.html

Typegoose enum arrayProp returns an error: Type is not a constructor

I have got a problem with the definition of my array schema. So basically, what I wanted to achieve is a single user Model with a property called games, that holds an array of games user is playing. The problem is I have got defined games as enum:
module Constants {
export enum Games {
LOL = 'League Of Legends',
}
}
export {Constants};
And now, when I try to attach it to the schema model like that:
#arrayProp({ required: true, items: Constants.Games })
games: Constants.Games[];
I receive an error (after a successful compilation, just before the server start)
^ const instance = new Type();
TypeError: Type is not a constructor
at baseProp (C:\Users\Borys\Desktop\lft\backend\node_modules\typegoose\lib\prop.js:114:22)
at C:\Users\Borys\Desktop\lft\backend\node_modules\typegoose\lib\prop.js:177:9
at DecorateProperty (C:\Users\Borys\Desktop\lft\backend\node_modules\reflect-metadata\Reflect.js:553:33)
at Object.decorate (C:\Users\Borys\Desktop\lft\backend\node_modules\reflect-metadata\Reflect.js:123:24)
at __decorate (C:\Users\Borys\Desktop\lft\backend\build\dataModel\User.js:4:92)
at Object.<anonymous> (C:\Users\Borys\Desktop\lft\backend\build\dataModel\User.js:64:1)
I have read a little bit about this error, but it relates to the required option for items/itemsRef I tried removing required, using enum, using even itemsRef and relating to the different set of documents but none of these worked for me.
Anyone could help/relate?
The problem is, you cannot use enums as an runtime mongoose type, so i would recommend using
#prop({ required: true, type: String, enum: Constants.Games })
games: Constants.Games[];
type for setting the type (which is string) (this option can be omitted - thanks to reflection)
enum for setting an enum to validate against
#arrayProp({ required: true, items: String })
games: Constants.Games[];
is a solution to this problem.
I would appreciate it if anyone could clarify and tell me more about why shouldn't I use enum in the items property.

How would i make the mongoose Schema dynamically according to the other fields value in node.js?

i want to define the schema dynamically according to the condition using mongoose
Schema
new mongoose.Schema({
type: String, //BASIC OR ADVANCE
// only for type = BASIC
name: String,
age: Number
/*
want these fields too but only if type = ADVANCE
email: String,
password: Number
PhoneNumber: String
*/
});
how would i achieve this kind of schema using mongoose.
it depends on what your approach to your database is. you can simply create two types with identifiers as Advance and Basic and use middleware to maintain the flow. Now to answer your question:
something like:
new mongoose.Schema({
type: String, //BASIC OR ADVANCE
// only for type = BASIC
name: String,
age: Number,
advance: []
And now you can check if advance is empty or not. Seriously it all depends on your approach, how you deal with the problem. Once a Schema is declared you can without the advance field, you can still save data like:
const MyModel = mongoose.model('Test', new Schema({ name: String }));
const doc = new MyModel();
doc.advance = {
email: "test#test.com",
password: 1234,
PhoneNumber: 1234
}
doc.save();
But with this structure if you want to know the Schema, you'll think that in your file it is only name and age and later when you start exploring, you'll find out that you are doing something like this and using a proper structure.
Think of moongoose documents as JavaScript Objects, there is a reason it is known as non-Structured data. Hope this explanation helps.

how to validate dynamic key of mongoose schema

I am trying to build a MEAN project, so I need to validate some of my model's dynamic key...
I want to create a Schema like this
var exampleSchema = new Schema({
x: {
type: String,
default: '',
required: true,
trim: true
},
y: {}
});
as you see I have mixed type object, but actually it is a Language Map and it should be something like this,
{
"en-US": "answered"
}
can I validate my key with mongoose? (I think it has no function like that)
if no, how and where can I validate it (in model or controller)?
You may want to look into this: http://mongoosejs.com/docs/middleware.html
Specifically pre-save events. Mongoose gives you control over this and you can perform validation, mapping as needed before the actual model gets saved.
Also works nice for pre-init event if you need defaults such as "current date" for an audit trail such as "createdOn: date".

How to update a mongodb/mongoose schema from a single value field to a multi value field

I have a schema defined in Mongoose like this:
var Stuff = new Schema({
href: String,
thing: Number,
});
But now the "thing" field is more complicated than a single number, so I'd like to update my model make "thing" have embedded fields:
var Stuff = new Schema({
href: String,
thing: { thinglabel: String,
thingvalue: Number}
});
I'm wondering if there is an elegant way to do this. For the time being, I've hacked around this problem by adding a second field but I was thinking that there might be a better solution the next time I run into this problem.

Resources