how to convert mongoose js model to object - node.js

i am working with node.js and mongoosejs framwork for mongodb. I am trying to convert a mongoose model to an object, I was able to do that, but am getting only fewer elements rather than getting all. Below code which I tried.
user.js
var schema = new Schema({
name:{ type:string },
title:{ type:string, default:"mr" }
});
module.exports = mongoose.model('Users', schema);
usermanager.js
var User = require(../user.js);
var user = new User();
console.log(user.toString());
//printed as {_id:2583457assda312, title:'mr'}
i am expecting name key in that object. i have also tryed toObject it also giveing me the same response.
ther is any posiblty to achive this?

Your usage is intended to be like this:
var user = new User({ name: "Fred" })
and you will get the values from what you have defined, so in this case:
//printed as {_id:2583457assda312, name: "Fred", title:'mr'}
Or you supply your title as here:
var user = new User({ name: "Wilma", title: "Ms" })
and again get your output
//printed as {_id:2583457assda312, name: "Wilma", title: "Ms"}
If what you are trying to do is inspect the schema there is a paths property on Mongoose schema objects
console.log( user.schema.paths )
And that should give you a definition of the various parts of the schema you defined.

Related

document must have an _id before saving mongoose error

I am trying to create a schema.
I keep getting the document does not have an _id error, besides the code below I did try to initialize it explicitly, but nothing works.
var UserSchema = new mongoose.Schema({
_id: mongoose.Schema.ObjectId,
username: String,
password: String
});
var User = mongoose.model('user', UserSchema);
http://mongoosejs.com/docs/guide.html#_id reads:
Mongoose assigns each of your schemas an _id field by default if one is not passed into the Schema constructor.
If you explicitly define _id type in the schema, it's your responsibility to set it:
User._id = mongoose.Types.ObjectId('000000000000000000000001');
_id is the primary key for document in a mongoDB. You don't have to specify the _id in your Schema. It will be added automatically once the document is created.
Here is the sample code:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var User = new Schema({
username: {
type: String
},
password: {
type: String
}
});
module.exports = mongoose.model('User', User);
I think you dont need to define the _id. Try without and see if it works.
Also if that is not the problem try this:
_id: { type: Mongoose.Schema.Types.ObjectId }
if you want to define _id in your schema explicity you should assign a value to "_id" for each insertation. you have two way to solve this problem :
1. remove "_id" from your schema and mongoose generate id automatically.
2. assign a value to _id :
var ObjectId = require('mongodb').ObjectID; // or var ObjectId = require('mongoose').Types.ObjectId; "but the first worked for me"
User._id = objectId('1111111111111111111');
simple remove the line from your code
_id: mongoose.Schema.ObjectId

How to get a list of available Mongoose Discriminators?

Given a situation where you have a User Scheme that you use to create a base model called User. And then for user roles, you use mongoose discriminators to create inherited models called Admin, Employee and Client. Is there a way to programmatically determine how many discriminations/inheritances/roles of the User model are available, as well as the available names?
My question in terms of code:
File: models/user.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var options = {discriminatorKey: 'role'};
var userSchema = mongoose.Schema({
name: String,
email: String,
password: String,
},options);
var User = mongoose.model('User', userSchema);
var Client = User.discriminator("Client", mongoose.Schema({
Address : String,
Tax_identification : String,
Phone_number : String,
Internal_Remarks : String,
CRM_status : String,
Recent_contact : String,
}));
var Employee = User.discriminator("Employee",mongoose.Schema({
Staff_Id: String,
}));
module.exports = {User: User, Client: Client, Employee: Employee };
File: controllers/usersController.js
var User = require('../models/user.js').User;
module.exports = {
registerRoutes: function(app){
app.get('user/create',this.userCreateCallback)
},
userCreateCallback: function(req,res){
//Get Available User Roles - The function below doesn't exist,
//Just what I hypothetically want to achieve:
User.geAvailableDiscriminators(function(err,roles){
res.render('user/create',{roles:roles})
});
}
};
I hope I managed to express what I want to do. Alternative approaches are also welcome.
Since v4.11.13, mongoose model has model.discriminators which is an array of models, keyed on the name of the discriminator model.
In your case if you do console.log(User.discriminators) you will get:
{
Client: {
....
},
Employee: {
}
}
As far as I can see, this is not documented anywhere.
Line 158 in lib.helpers.model.discriminators.js is where this is created.
I think you want to fetch the names and values of all the discriminators as for the names you can simply use
User.discriminators
but for finding values you can use this
return Promise.all(Object.keys(discriminators).map(i =>
discriminators[i].find({ userId: this._id }))
).then(promiseResults =>
promiseResults.reduce((arr, el) => arr.concat(el), [])
);
you need to put userId under each discriminators for that.

Nested objects are not update

Allora, I'm using mongoose for the first time and I decided to create 2 schemes: the first one represents a user and the second one represents his enquires. Users have an array of enquires like:
var userSchema = new mongoose.Schema({
name: String,
enquires: { type : [Enquire.schema] , "default" : [] },
});
var enquireSchema = new mongoose.Schema({
status: {type: String, 'default': 'pending'},
enquire: String,
});
I see that if I search for an enquire and update its status, it doesn't update the same enquire on the user's array, meaning that they are different object. I don't want to save an array of IDs as it will be the same as a relational database, so I see only 1 solution which is forgetting about the enquire scheme and use only the User scheme. Is it the way mongoose works? For every relationship do I have to insert everything like nested object?
I think you should use references to achieve what you want to achieve.
For more information on mongoose references and populate see Mongoose Populate documentation.
Try this, It may help you.
User Schema :
var userSchema = new mongoose.Schema({
name: String,
enquires: [{ type : mongoose.Schema.Types.ObjectId , ref : 'Enquiry' }]//array of enquiries
});
var User = mongoose.model('User',userSchema );
module.exports = User;
Enquiry Schema :
var enquireSchema = new mongoose.Schema({
status: {type: String, 'default': 'pending'},
enquire: String,
});
var Enquiry = mongoose.model('Enquiry',enquireSchema );
module.exports = Enquiry ;
Working :
create a new Enquiry.
Push it's ID(_id) into user's enquires array.
var enquiry = new Enquiry();
enquiry.enquire = "Dummy enquiry";//set the enquiry
enquiry.save(function(err,result){
if(!err){
//push 'result._id' into users enquires array
}
});
whenever you update an enquiry, it will be automatically updated in
user's document.
use populate to retrieve user's enquiries.
You can embed sub documents (entity) which has id and is like a document or embed native array like a normal property.
And I think the correct definition for yours is :
var enquireSchema = new mongoose.Schema({
status: {type: String, 'default': 'pending'},
enquire: String,
});
var userSchema = new mongoose.Schema({
name: String,
enquires: { type : [enquireSchema] , "default" : [] },
});
If you use refs in embedded link then there are two separate collections and be like relational db's.

Testing Mongoose model required properties

I recently started developing apps with node.js, express, and mongoose. I decided to use mocha as a testing framework and is wondering how would I unit test mongoose.model properties for validity.
So if I had a model defined like this:
var userSchema = new Schema({
name: {type: String, required: true}
});
var userModel = new mongoose.model('User', userSchema);
I'm assuming that stating "require: true" means that userSchema.name must be defined and not null.
How do I test that when I instantiate a userModel, I must provide it with an object containing a name property that is not null or undefined?
Thanks
Check out Mockgoose for writing unit tests with mongoose models without the need to have a mongodb instance running.
You could write a simple test like this:
var mongoose = require('mongoose'),
mockgoose = require('mockgoose');
mockgoose(mongoose);
var Schema = mongoose.Schema;
var SimpleSchema = new Schema({
name: {
type: String,
required: true
}
});
mongoose.model('SimpleModel', SimpleSchema);
it('fails to save document with missing name', function(done) {
var simpleModel = new SimpleModel({
name: undefined
});
simpleModel.save(function(err) {
should.exist(err);
done();
});
});
Then define different tests with different values for name (null, undefined, etc.) or even an empty object (i.e. an object without name property).

Saving Mongoose object into two collections

Currently I have a node application which uses mongoose to save an object into a MongoDB. I am using a model similar to this:
var mongoose = require('mongoose')
, Schema = mongoose.Schema;
var RegistrationSchema = new Schema({
name:{ type: String, default: '', trim: false}
});
mongoose.model('Registration', RegistrationSchema);
Which saves my objects into a collection called registrations.
I save my registrations as such:
var registration = new Registration(data);
registration.save(function(err) {
if (err) {
return callback({
source: 'data_save',
type: 'admin',
errors: err
});
}
else {
return callback(null, data);
}
});
I would also like to save this same object when I create it, into another collection with a different name, such as registrations_new, or something to that effect. I want to duplicate this entry into the new collection. I tried to add the other collection in the connection string, which broke the mongo part entirely, I tried to create a new model called New_Registration, load that Schema and try to save it individually, but I have another issue with that. It seems that Mongoose pairs the schema with the collection, and that there really is no way to overwrite which collection it is saving to.
Anyone have any solution for this?
You can use the same schema in multiple models, so something like this works:
var RegistrationSchema = new Schema({
name:{ type: String, default: '', trim: false}
});
var Registration = mongoose.model('Registration', RegistrationSchema);
var New_Registration = mongoose.model('New_Registration', RegistrationSchema);
var registration = new Registration(data);
registration.save();
var new_registration = new New_Registration(data);
new_registration.save();

Resources