Mongoose saving empty array - javascript

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)

Related

how to return a Mongoose nested array of objects

I am trying to return a nested Object that I declared in my mongoose model as follows:
const MessageSchema = new Schema({
messageLog: [
{
transcript: {
type: String
},
recipient: {
type: Schema.Types.ObjectId,
ref: 'User',
required: true
},
sender: {
type: Schema.Types.ObjectId,
ref: 'User',
required: true
}
}]
});
however I am not able to get the value for the inner object back when I try to query for it via a graphql resolver (transcript, sender, recipient are null on gql playground, but updated in db) I have set it up as follows:
query = args.messageId ? { _id: args.messageId } : { _id: new ObjectId() };
const message = await Message.findOneAndUpdate(query, {$addToSet: {messageLog: {transcript: args.messageBody, sender: args.senderId, recipient: args.recipientId}}}, {$setOnInsert: args, upsert: true, new: true, runValidators: true})
return message.messageLog;
I am able to create the new object and the nested messageLog in the db but I can only return the id for some reason as opposed to the the messageLog array of objects. Usually the issue lies in how I am resolving (resolvers) but I am going to put my typeDef here as well in case the issue lies there.
type Message {
_id: ID
transcript: [String]
recipient: [User]
sender: [User]
}
So the solution in case anyone has a similar schema setup and issue is to reference the the typeDefs with the nested levels as well. So since transcript, recipient and sender were nested a level down, the typeDef would have to be defined for the nested object and then referenced on the message type as follows:
type messageLog {
_id: ID
transcript: String
recipient: User
sender: User
}
type Message {
_id: ID
messageLog: [messageLog]
}
and to use populate for the User since it was a schema referenced by the objectId

Mongoose populate and search by populated field

I am trying to do a simple search on a field that is a ref of another collection. Say I have the example collection of Invoices with a reference to a collection named client. So the example schema would look like so:
const invoiceSchema = new Schema({
name: {
type: String,
required: true
},
amount: {
type: Number,
required: true
},
client: {
type: Schema.Types.ObjectId,
ref: 'Client'
},
}
Then I have the client schema like so:
const clientSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
}
}
What I want to do is query the invoice schema and search for the name field in the client.
I have tried to use find and match with populate but that just returns the entire invoices collection and the client field is null on all of them:
const q = new RegExp(req.body.q, 'i');
invoices = await Invoice.find().populate({
path: 'client',
match: {
name: q
}
});
So how should I go about searching for a populated field with mongoose?

Mongoose schema either single object or array of objects based on condition

I have the following schema:
const contentSchema = new Schema({
name: {
type: String,
required: true
},
type: {
type: String,
required: true
},
value: {
type: String,
required: true
}
});
const contentArraySchema = new Schema({
contentArray: [contentSchema]
});
const pageSchema = new Schema({
contents: [contentSchema]
});
I would like to have a mix of objects and arrays added to the pageSchema. If I have an array I would like to populate it with the contentSchema objects and then add that to the pageSchema contents field array. If I don't have an array I would just like to add the contentSchema object to the pageSchema contents field array.
I was just going to use the mixed schema type but I'm not sure what the best way to go about doing this would be and what effect that would have on basic database searching.
I also thought about doing something like I saw on this post Here:
pageSchema.pre('validate', function (next) {
if (type === 'array') {
//use content array schema
} else {
//use regular content schema
}
next()
});
But I'm not really sure what the best practice is for something like this. Hopefully someone has some experience with this and can help. Thanks.

How to troubleshoot a mongoose object save?

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);

Array of ObjectIds will not populate without error

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.

Categories