Mongoose array of objects are empty when saved - node.js

I am trying to save an array of objects to mongoose but this saves only an empty array in database. The below is model and schema
const HoldingSchema = new Schema({ symbol: String, quantity: Number });
const UserSchema = new Schema({
_id: {
type: String,
required: true,
},
holdings: {
type: [HoldingSchema],
default: undefined,
},
});
const UserModel = mongoose.model('Users', UserSchema, 'Users');
I try to store an array of objects with the below code. But this creates an empty array in the place of holding.
const testuser = new userModel({
_id: '001',
holding: [{ symbol: 'itc', quantity: 100 }],
});
await testuser.save(); // creates { _id: '001', holdings: [], __v: 0 }
Is it not possible to store array of custom objects. If not what would be an alternative?

There is actually a typo in your code that is why it doesn't save your holdings.
You have written holding, while the field is actually holdings
const testuser = new userModel({
_id: '001',
holdings: [{ symbol: 'itc', quantity: 100 }],
});

Related

getting a CastError, ObjectId failed for value

I have a route that is inserting an array of documents into a collection. I also want to capture the _is of the document into a user schema but I'm getting a CastError, how do I resolve this. here is my code:
the error:
(node:23088) UnhandledPromiseRejectionWarning: CastError: Cast to ObjectId failed for value "
{
_id: 6032c1df6761405a308736f0,
name: ' test1',
surname: 'test',
email: 'example#example.com',
phone: '0915461',
__v: 0
},
{
_id: 6032c1df6761405a308736f1,
name: 'jane',
surname: 'doe',
email: 'jane#gmail.com',
phone: '12345678',
__v: 0
}
]" at path "references"
route:
app.post('/register_two/:id/references', async (req, res) => {
const staff = await Worker.findById(req.params.id);
const reference = await Reference.insertMany(req.body.references);
await staff.references.push(reference); <<--- Error when i try to push document IDs
});
my reference schema:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const ReferenceSchema = Schema({
name: String,
surname: String,
email: String,
phone: String
});
module.exports = mongoose.model('Reference', ReferenceSchema);
my worker schema
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const WorkerSchema = new Schema({
name: String,
surname: String,
role: String,
nationality: String,
gender: String,
dateofbirth: Date,
contactnumber: String,
email: String,
address: String,
region: String,
righttowork: String,
righttoworkproof: String,
ninumber: String,
references: [
{
type: Schema.Types.ObjectId,
ref: 'Reference'
}
],
date: Date
});
module.exports = mongoose.model('Worker', WorkerSchema);
edit: fixed worker schema
I managed to solve it using the spread operator, all I did was change:
await staff.references.push(reference);
to
await staff.references.push(...reference);
You should run the insertMany command with the rawResult option set to true
const reference = await Reference.insertMany(req.body.references, {rawResult: true});
This way you will get the raw result from the MongoDB driver back into reference. That result will be an object that will contain this prop:
...
...
insertedIds: { '0': 6032ce0ed7fd8568aef0d0cd, '1': 6032ce0ed7fd8568aef0d0ce, ... }
...
insertedIds is what you need, but you need them in the form of an array. So here is what your code should look like:
const reference = await Reference.insertMany(req.body.references, {rawResult: true});
await staff.references.push(...Object.values(reference.insertedIds));
Credit to Emil C., who pointed out that by pushing an array we would simply be creating array of arrays inside the reference path. Spreading is the answer.

Find Object and Update by pushing to nested Array in MongoDb

I have created a Mongoose Model which holds nested arrays exercises>history>data. I want to make a put request and push an Object, consisting of the time the data was createdAt as well as an array of the Users data to the history of the exercise that was run. However, the following attempt did not work:
User.findOneAndUpdate(
{ _id: req.user.id, "exercises.title": req.body.exercise_title },
{ $push: { "exercises.$.history": { data: [1,2,3,4,5] } } }
);
My Schema looks as follows:
const mongoose = require('mongoose');
const UserSchema = new mongoose.Schema({
userName:{
type: String,
required: true},
exercises:[{
title:{
type: String,
},
history: [{
createdAt: {
type: Date,
default: Date.now
},
data: []
}]
}]
});
module.exports = mongoose.model('User', UserSchema)
I have no clue why my query is not working

Match specific value in mongoose populate

Following is the schema of a user collection:
const Mongoose = require('mongoose')
const Schema = Mongoose.Schema
const userSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String
},
supporterOf: [{
type: Schema.Types.ObjectId,
ref: 'individual',
required: false
}],
})
module.exports = Mongoose.model('user', userSchema);
I want to populate 'supporterOf' which is a collection of individual (ref: individual).
The 'supporterOf' contains an array of ObjectId.
I am having the problem of matching the specific objectId with that ObjectId array.
Can anyone suggest me how I can match specific ObjectId with an array of ObjectIds in populate function?
You have a reference of 'individual' in supporterOf and you want to populate only relevant object from the array of individuals?
If this is right case then do the following:
YourUserModel.findById(userId, function (err, user) {
console.log(user)
}).populate({
path: 'supporterOf',
match: {
yourObjectOfIndividualDocument: yourMatchingIdOfIndividual
}
})
.exec()
Replace yourObjectOfIndividualDocument: yourMatchingIdOfIndividual by name: 'abcd'.
Here name is the field of Individual document not of User document.
You add condition in populate
if you wanted to populate fans array based on their age, and return, at most, any 5 of them
.populate('fans', null, { age: { $gte: 21 }}, { limit: 5 })

How to push data into array using mongoose, with schema having single only single object

I am learning Mongoose, and got struct on pushing data into array blogs.
my schema is
module.exports = function(mongoose) {
var UserSchema = new Schema({
count:String,
_id : {id:false},
blogs: [{ type: Schema.Types.ObjectId, ref: 'Blog' }]
},
{
timestamps: { createdAt: 'created_at', updatedAt: 'updated_at' }
});
var BlogSchema = new Schema({
blogs:[{
post : String,
title: String,
author : String,
userId: {
type: String,
default: function() {
return crypto.randomBytes(12).toString('hex');
}
},
_id: {type: String, required: true}
}],
});
var models = {
User : mongoose.model('User', UserSchema),
Blog : mongoose.model('Blog', BlogSchema)
};
return models;
}
Problem is here userSchema will always have/be a single object, whcih will keep track of count of total blogs.
I know it can be done using findOneAndUpdate but I don't have id/object created for UserSchema.
Any help is appreciated. Thanks

associative array does not save mongoose

tournament.js
var mongoose = require('mongoose');
var TournamentPlayer = require('../models/tournamentPlayer');
var SportPlayer = require('../models/sportPlayer');
var Schema = mongoose.Schema;
var TournamentSchema = new Schema({
tournamentPlayers:[{
type: Schema.Types.Mixed,
ref: 'TournamentPlayer'
}],
buyin: Number,
entrants: Number,
prizePool: Number,
name: String,
sport: String,
endOfRegistration:Date,
sportsPlayers:[{
type: Schema.Types.Mixed,
ref: 'SportPlayer'
}],
created: {
type: Date,
default: Date.now
}
});
module.exports = mongoose.model('Tournament', TournamentSchema);
api.js
tournament.tournamentPlayers[player.userId]=player;
console.log("ass array"+util.inspect(tournament.tournamentPlayers,false,null));
console.log("ass array element" + util.inspect(tournament.tournamentPlayers[player.userId] ,false,null));
console.log("ass array just in case"+util.inspect(tournament.tournamentPlayers,false,null));
tournament.tournamentPlayers.push(player);
console.log("push"+util.inspect(tournament.tournamentPlayers,false,null));
Output
ass array[]
ass array element{ username: 'batman',
roster:
{ __v: 0,
userId: '57bb89eb10c4b4ac124980b9',
tournamentId: '57d49f5169cc78ac21c5e791',
_id: '57d4b421315f1b501ad5456f',
playerRoster:
[ { _id: '57cfe922dcba0f295f57e26d', playerFirstName: 'Julio' },
{ _id: '57cfe939dcba0f295f57e274', playerFirstName: 'Odell' } ] },
rank: 'blah',
totalPoints: 0,
userId: '57bb89eb10c4b4ac124980b9',
_id: '57d4b421315f1b501ad54570' }
ass array just in case[]
push[{"username":"batman","roster":{"__v":0,"userId":"57bb89eb10c4b4ac124980b9","tournamentId":"57d49f5169cc78ac21c5e791","_id":"57d4b421315f1b501ad5456f","playerRoster":[{"_id":"57cfe922dcba0f295f57e26d","playerFirstName":"Julio"},{"_id":"57cfe939dcba0f295f57e274","playerFirstName":"Odell"}]},"rank":"blah","totalPoints":0,"userId":"57bb89eb10c4b4ac124980b9","_id":"57d4b421315f1b501ad54570"}]
I am trying to declare and add objects to an associative array. When I look them up, I want to use userId instead of _id. When trying with this code, the object can be called directly tournamentPlayers[userId], but doesn't display as part of the array tournamentPlayers. When I do a regular push, it displays, but this isn't what I want. I am able to use the object, but can't save it through mongoose.
I've seen a couple of questions but they did not answer this. The second answer here has strict: false as a setting, but not for a single schema element.
Mongoose: Saving as associative array of subdocuments vs array of subdocuments
How can I declare and add objects to an associative array in mongoose?

Resources