I have a node.js api built out that updates a subdocument. Below is the post call for the subdocument:
.put(function(req, res) {
member.findById(req.params.member_id, function(err, member) {
if (err)
res.send(err);
console.log("old: " + member);
member.address[req.params.address_id].address_type = req.body.address_type;
member.address[req.params.address_id].street1 = req.body.street1;
member.address[req.params.address_id].street2 = req.body.street2;
member.address[req.params.address_id].City = req.body.City;
member.address[req.params.address_id].State = req.body.State;
member.address[req.params.address_id].Zip = req.body.Zip;
member.address[req.params.address_id].Lat = req.body.Lat;
member.address[req.params.address_id].Lng = req.body.Lng;
console.log("new: " + member);
member.save(function(err) {
if (err)
res.send(err);
res.json({message:'Address Updated!!!'});
})
})
})
The two console.log lines prove that the object was found in the findById call, then updated after going through the array. The logs prove that the object in memory is in fact updated.
However, when actioning the .save() call, I get the success message, but nothing changes in mongodb.
I get no errors, no warnings, nothing. It says success, but no change.
How do I troubleshoot?
here's my Address Model:
var mongoose = require('mongoose'),
Schema = mongoose.Schema
var AddressSchema = Schema({
Address_type : String,
street1 : String,
street2 : String,
City : String,
State : String,
Zip : Number,
Lat : Number,
Lng : Number
});
module.exports = mongoose.model('Address', AddressSchema);
and here's the parent model, member:
var mongoose = require('mongoose'),
Schema = mongoose.Schema
var Address = require('./address');
var Award = require('./award');
var MemberSchema = Schema({
FName : String,
LName : String,
address: [Address.Schema],
phone : {
type : String,
number : String
},
email: String,
gender: String,
DOB: Date,
rank : {
level : String,
updated: { type: Date, default: Date.now }
},
Awards : {
personal : Boolean,
award : [Award.Schema],
granted: { type: Date, default: Date.now }
}
});
module.exports = mongoose.model('Member', MemberSchema);
When you update an array element of a Mongoose document via its index it doesn't trigger the change detection of the array so Mongoose doesn't know to save it (see the FAQ).
To manually trigger the change detection, you can call markModified before your call to member.save:
member.markModified('address');
To help troubleshoot these types of problems, enable Mongoose's debug output to see the actual calls it's making to the native driver by adding the following to your startup code:
mongoose.set('debug', true);
Related
I have problem using uuid with new mongoose.Schema. I use it to generate unique key for a device and save it to the MongoDb using Node.js. the problem is that it uses the same UUID every time.
This is the model:
const mongoose = require('mongoose');
const uuid = require('uuid/v4');
const DeviceSchema = new mongoose.Schema({
deviceNumberHash: {
type: String,
required: true
},
receivingKey: {
type: String,
default: uuid()
}...
});
And this is what is saved in MongoDb:
Any idea what's wrong?
You're calling uuid and passing its return value in as the default to use.
Instead, pass in the function (by not putting () after it):
const DeviceSchema = new mongoose.Schema({
deviceNumberHash: {
type: String,
required: true
},
receivingKey: {
type: String,
default: uuid // <========== No ()
}...
});
The default can be a function per the docs (an example there uses default: Date.now to provide a default for a date field, for instance).
I have a array and i trying to insert it with mongoose but in return i got a empty array what i'm doing wrong,
my schema:
let postSchema = mongoose.Schema({
date : { type: Date, default: Date.now },
name : String,
desc : String,
type : []
},{collection: 'Post'});
my insert:
console.log(req.body.type); //here i have something like ["Teste1","Teste2"]
let post = new Post({
name: req.body.descricao,
desc: req.body.desc
type: req.body.type
});
post.save((err, model) => {
if (err) console.log(err);
if (model) console.log(model); //ALL INSERTED but array is just type:[]
})
The best way is to specify the type of the array elements.
For example,
type: [String]
Specifying an empty array is equivalent to Mixed type.
Also check the type of req.body.type
console.log(typeof req.body.type)
I guess it's a stupid question but i would like do something like this
var mongoose = require('mongoose');
var Long = require("long");
var UserSchema = new mongoose.Schema({
id: Long(),
name: String,
completed: Long(),
note: String,
updated_at: { type: Date, default: Date.now },
});
But it's not working,"cannot set 'low' property". I know that cause I do not pass arguments in the "Long" constructor but it's not working iven if I don't put the "()". I'm a bit lost with that ^^'
Sorry for my english ^^'
You should use a module specifically designed for Mongoose, like mongoose-long:
var mongoose = require('mongoose')
require('mongoose-long')(mongoose);
var Long = mongoose.Schema.Types.Long;
var UserSchema = new mongoose.Schema({
id : Long,
name : String,
completed : Long,
note : String,
updated_at : { type: Date, default: Date.now },
});
I reuse a project About Node and Passport that use mongodb, where a schema is defined as the following, in a user.js file
var mongoose = require('mongoose');
var userSchema = mongoose.Schema({
local : {
email : String,
password : String,
},
facebook : {
id : String,
token : String,
email : String,
name : String
},
twitter : {
id : String,
token : String,
displayName : String,
username : String
},
google : {
id : String,
token : String,
email : String,
name : String
}
});
module.exports = ('User', userSchema);
As i'm using mysql, I'm trying to keep that object structure, for the rest of the code.
So how can I define an object like this, to be able to instantiate it, to then work on it like :
var User = require('../app/models/user');
var newUser = new User();
newUser.local.email = "babab";
newUser.local.password = "bababab";
Probably a trival question, but I'm a bit lost with the javascript object handling.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript
What you're looking for is javascript prototypes
edit: here's an article for node specifically,
http://howtonode.org/prototypical-inheritance
Following #kirinthos, various solution appears. I select the most basic one (I think), but comment and improvement are welcome:
The object definition
module.exports = Object({
id : String,
local : {
email : String,
password : String,
},
facebook : {
id : String,
token : String,
email : String,
name : String
},
twitter : {
id : String,
token : String,
displayName : String,
username : String
},
google : {
id : String,
token : String,
email : String,
name : String
}
});
The object instancitation :
var User = require('../app/models/user');
var newUser = Object.create(User);
newUser.local.email = "babab";
newUser.local.password = "bababab";
I have the following mongoose schema:
var ChatSchema = new Schema({
pin: String,
users: [{type: mongoose.Schema.Types.ObjectId, ref: "User"}],
messages: [{type: mongoose.Schema.Types.ObjectId, ref: 'Message'}], //<----
active: Boolean,
});
var MessageSchema = new Schema({
sent: Date,
user: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
content: String
});
var UserSchema = new Schema({
name: String,
pin: String,
id: String
});
This function is defined for the ChatSchema:
ChatSchema.methods.addMessageForUser = function(message, userid, userpin ) {
chat = this;
module.exports.User.findOne({id: userid, pin: userpin}).populate('messages').exec(function(err, user) {
message = {
user: user,
time: new Date(),
message: message,
};
chat.messages.push(message);
chat.save();
});
};
When I run it, I get the following error:
CastError: Cast to ObjectId failed for value "[object Object]" at path "messages"
If I remove populate('messages);` Then the error goes away, but I get another error because I try to use the messages array.
Here is the code for the models:
module.exports.Message = mongoose.model('Message', MessageSchema);
module.exports.User = mongoose.model('User', UserSchema);
module.exports.Chat = mongoose.model('Chat', ChatSchema);
Based on what you've got here, you're trying to populate backwards.
If each User had an array of Messages, then this populate call would work. It's a method on the mongoose Query object, in this case, and so it's looking for a property called messages on the documents in the User collection you're querying to pull ids from - since these aren't there, you get a weird error.
Based on what you've got here, it looks like it will work if you just remove the populate call.