How to populate a group in mongoose - javascript

I have this in my mongoose schema...with some group...
'use strict';
var mongoose = require('mongoose')
, Schema = mongoose.Schema;
var clientSchema = new mongoose.Schema({
name : { type: String },
offerings : [{ type: String }],
cscPersonnel : {
salesExec : { type: Schema.Types.ObjectId, ref: 'User' },
accountGM : { type: Schema.Types.ObjectId, ref: 'User' },
},
},
netPromoterScore : { type: Number }
});
module.exports = mongoose.model('clients', clientSchema);
I tried to populate reff dis way...I have also populated in ref (user as {path:'cscPersonnel'})
function getOneById(id){
var deferred = Q.defer();
console.log("im in get by id" +id);
model
.findOne({ _id: id })
.populate({path:'cscPersonnel'})//one way
/* 'cscPersonnel salesExec', //second way
'cscPersonnel accountGM', */
.exec(function (err, item) {
if(err) {
console.log(err);
deferred.reject(err);
}
else
console.log(item);
deferred.resolve(item);
});
return deferred.promise;
} // gentOneById method ends
but unfortunatly ended up with this error!!!!
CastError: Cast to ObjectId failed for value "[object Object]" at path "_id"
{
"message": "Cast to ObjectId failed for value \"[object Object]\" at path \"_id\"",
"name": "CastError",
"type": "ObjectId",
"value": {
"salesExec": "56cf5f09245f8a240b30693b",
"accountGM": "56cf5f09245f8a240b30693b"
},
"path": "_id"
}
how to make it solve this issue.... do help , thanks in advance

Please try this one
model
.findOne({ _id: id })
.populate({path: 'cscPersonnel.salesExec'})
.populate({path: 'cscPersonnel.accountGM'})
.exec(function (err, item) {

Related

Mongoose mixed Type object array, can findOneAndUpdate

I have a controller edit card which updates the fields of cardsArray object.
cardsArray is mixed type object as fileds of each card object is different so i am storing mixed.type
Althought pushing new card using addCard controller works perfectly
But when edit card controller is called, it gives type error
When edit Controlller is callled is gives following error:
TypeError: Cannot read properties of null (reading 'cardsArray')
// Schema
const userSchema = new mongoose.Schema(
{
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
cardsArray: [{ type: mongoose.Schema.Types.Mixed }],
}
);
//__Mongodb Data
{
"_id": {
"$oid": "63b43ab32fc8d3c100cafecc"
},
"name": "usern_name",
"email": "pr****#gmail.com",
"password": "$2b$12$3nwifHakrBu94BwLXAC4Nu16Kw0.xyW8vAIPTMSgY7cYttVklDIZq",
"cardsArray": [
{
"title": "some_title",
"category": "Bank",
"cardHolder": "some_name",
"cardNumber": "54545454",
"expiry": "23/01",
"cvv": "***",
"logoIndex": 72,
"isFavourite": false,
"_id": {
"$oid": "63b83cc77288d277ef359533"
}
}
],
"loginIdsArray": [],
"docsArray": [],
"activitiesArray": [],
"__v": 0
}
// Add Card Controller.js___
addCard: async (req, res) => {
console.log(req.body.data, req.body.user_id)
// console.log('obj_id', newObjectId)
req.body.data._id = newObjectId;
try {
const response = await UserDatabase.findOneAndUpdate(
{ _id: req.body.user_id },
{
$push: {
// cardsArray: req.body.data,
cardsArray: { $each: [req.body.data] },
},
},
{ returnOriginal: false }
);
res.status(200).send(response);
} catch (error) {
console.log(error)
res.status(404).json({ message: error.message });
}
},
// edit card controller.js
editCard: async (req, res) => {
const id = req.params.id;
const { category, title, cardHolder, cardNumber, expiry, cvv, logoIndex, isFavourite } = req.body;
console.log(req.params.id)
try {
const response = await UserDatabase.findOneAndUpdate(
{ _id: "63b43ab32fc8d3c100cafecc", 'cardsArray._id': "63b709fc69a1cfa6fccd645c" },
{
$set: {
"cardsArray.$.title": req.body.title,
"cardsArray.$.category": req.body.category,
"cardsArray.$.cardHolder": req.body.cardHolder,
"cardsArray.$.cardNumber": req.body.cardNumber,
"cardsArray.$.expiry": req.body.expiry,
"cardsArray.$.cvv": req.body.cvv,
"cardsArray.$.logoIndex": req.body.logoIndex,
"cardsArray.$.isFavourite": req.body.isFavourite
}
},
);
console.log(response)
res.status(201).json(response.cardsArray);
} catch (error) {
console.log(error)
res.status(404).json({ message: error.message });
}
}
it means that there is no data matching the following _id and cardsArray._id
i thinks so its fails to find the feild 'cardsArray._id',first try finding the value by just findOne
await UserDatabase.findOneAndUpdate(
{ _id: "63b43ab32fc8d3c100cafecc", 'cardsArray._id': "63b709fc69a1cfa6fccd645c" })
if your find doesn't work try below methord not sure but it may work you have to either find the id and loop through the cardsArray of use $in or $match
await UserDatabase.findOneAndUpdate(
{ _id: "63b43ab32fc8d3c100cafecc", 'cardsArray':{$in:[ {_id:"63b709fc69a1cfa6fccd645c" }]})

Find One and Update in Mongoose with reference to other models is not working

I have a model named OrderModel and it has reference to other models as well
const orderSchema = new Schema({
_id: Schema.Types.ObjectId,
address: { type: addressSchema, required: false },
items: [{ type: Schema.Types.ObjectId, ref: 'Items' }],
date: { type: Date, default: moment(new Date()) },
user: { type: Schema.Types.ObjectId, ref: 'Users' },
is_completed: { type: Boolean, required: true, default: false },
is_canceled: { type: Boolean, required: true, default: false }
});
and when I want to update this model, using PATCH, it is giving me an error,
CastError: Cast to [ObjectId] failed for value "["5f0c9493f833e23a0028bd31,5f0c9429f833e23a0028bd2f"]" at path "items"
Here is how I do it in my code,
router.patch('/order', (req, res) => {
const query = { _id: req.body._id };
const _token = req.headers.authorization;
let data = req.body;
jwt.verify(_token, process.env.AUTH_TOKEN_KEY, (err, decoded) => {
console.log(query);
if (err) {
res.json({ message: 'Token Invalid'.err });
} else {
OrderModel.findOneAndUpdate(query, data, { new: true }, (err, doc) => {
console.log(doc,query);
if (doc) {
return res.json({ message: 'Succesfully saved', data: doc });
}
return res.json({ message: `No order found for id ${req.body._id}` });
});
}
})
})
i have two items as an Array, sent from frontend
{
"_id": "5f8f1b7b29cbed4a8495d646",
"items":"5f0c9493f833e23a0028bd31,5f0c9429f833e23a0028bd2f",
"user":"5f06060110b7881ac0244005",
"address":{
"line_1": "Address line 1",
"line_2": "Address line 1",
"city": "Los Angeles",
"state": "California",
"pin": "90210"
},
"is_completed": false,
"is_canceled": false
}
what am i doing wrong here?

mongoose findall return data from a different model

In users.js:
var mongoose = require('mongoose');
var User = mongoose.model('user', {
username: {
type: String,
required: true,
unique: true,
lowercase: true,
},
tasks: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Tasks',
}],
});
module.exports = User;
I then add a newUser named user1 and save to mongo.
The mongo doc looks like:
{
"_id" : ObjectId("574fb94f6a1e7d1826c16058"),
"username" : "user1",
"tasks" : [ ],
"__v" : 0
}
then try to fetch the document and it works fine in this handler:
In handlerA.js:
var User = require('../models/users.js');
module.exports.getUser = function(req, res){
User.findOne({username: "user1"}, function(err, data){
if(err){
console.log('getUser err', err);
res.send('ERROR')
} else {
console.log('getUser fx success = ', err, data);
res.send(data)
}
});
};
The result of the console.log:
getUser fx success = null { tasks: [], __v: 0, username: 'user1', _id: 574fb94f6a1e7d1826c16058 }
but same code fails in this other handler in a separate file.
In handlerB.js:
var User = require('../models/users.js');
module.exports.addStuff = function(req, res){
User.findOne({username: "user1"}, function(err, data){
if(err){
console.log('addStuff err', err);
res.send('ERROR')
} else {
console.log('addStuff fx success =', err, data);
res.send(data)
}
});
};
The result of the console.log:
addStuff fx success null null
Tried....and Failed....
I also tried this other solution from this question: Mongoose query return null
Mongoose pluralizes model names so it's running find on the "blogposts" collection instead of "blogpost". That said, your query in the mongo shell is on the "blogmodel" collection. In that case:
var BlogModel = mongoose.Model("BlogModel", ..)
or pass the collection name as the third param:
var BlogModel = mongoose.model("BlogPost", schema, "blogmodel")
This solution results in handlerA.js returning a null document as well as handlerB.js.
Thanks for your time. Much appreciated.
ADDENDUM.
I ran a find({}) under both the User and the Tasks models in handlerB.js
The returned document IN BOTH cases is based on the Tasks model.
see console.logs below for User.find({}) and Tasks.find({})
the err is the null value then the data.
How badly have I broken things? How can a Model.find return data that is not even in the model?
User.find({},funtion(err, data) ____________________
console.log of err then data
null
[ { subtasks: [],
team: [ [Object] ],
__v: 0,
maintask: '1',
_id: 574fce63d744cba421f750c1
},
{ subtasks: [],
team: [ [Object] ],
__v: 0,
maintask: '2',
_id: 574fce65d744cba421f750c2
}
]
Tasks.find({},function(err, data) ___________________
console.log of err then data
null
[ { subtasks: [],
team: [ [Object] ],
__v: 0,
maintask: '1',
_id: 574fce63d744cba421f750c1 },
{ subtasks: [],
team: [ [Object] ],
__v: 0,
maintask: '2',
_id: 574fce65d744cba421f750c2
},
]
This is the Tasks model...
tasks.js
var mongoose = require('mongoose');
var subtaskSchema = new mongoose.Schema({
subtask: {
type: String,
},
team: {
type: Array,
'defualt': [],
},
done: {
type: Boolean,
'defualt': false,
},
});
var Tasks = mongoose.model('tasks', {
maintask: {
type: String,
},
subtasks: {
type: [subtaskSchema],
},
team: {
type: Array,
'defualt': [],
},
done: {
type: Boolean,
'defualt': false,
},
});
module.exports = Tasks;
The mongoose docs suggest to define a model like so, did you try this?
var schema = new mongoose.Schema({ name: 'string', size: 'string' });
var Tank = mongoose.model('Tank', schema);

Mongoose findByIdAndUpdate not pulling

I am trying to pull an object from a subdocument in a mongodb. The structure is as follows (from db.users.find().pretty()):
{
"_id" : ObjectId("56a660b42819b770b89950bd"),
"userName" : "someGuy",
"itemCollection" : [
{
"item_name" : "item1",
"_id" : ObjectId("56a661232819b770b89950be")
}
],
"__v" : 13
}
This code:
var userID = req.user._id;
var transactionID = req.body._id;
console.log('userID: '+userID);
console.log('transactionID: '+transactionID);
User.findByIdAndUpdate(
userID,
{$pull: {'itemCollection': {'_id': transactionID}}},{new: true}, function(err, model){
if(err){
console.log('ERROR: ' + err);
}
console.log(model);
});
Gets me the following output:
> userID: 56a660b42819b770b89950bd
> transactionID: 56a661232819b770b89950be
> { itemCollection:
[ { item_name: 'item1',
_id: 56a661232819b770b89950be } ],
__v: 13,
userName: 'someGuy',
_id: 56a660b42819b770b89950bd }
So nothing seems to have happened. I've tried every variation on stack overflow that I could find but it never deletes it. Does anyone see what is wrong?
You need to convert your _ids from string to an ObjectID type:
var mongoose = require('mongoose');
var userID = mongoose.mongo.ObjectID(req.user._id);

Postman only posts to mongoose nested level 1

I'm trying to test a post to a mongoose schema that has nested fields, but I'm only able to level 1 and the first field in level 2. For example:
I have a network model that can contain multiple ip addresses and multiple subnets. When I place the query in to Postman it allows me to create multiple ip addresses and multiple subnets (great) but I can't define a type field for example?
Mongoose Schema:
var mongoose = require('mongoose'), Schema = mongoose.Schema, ObjectId = mongoose.Schema.ObjectId;
var networkSchema = module.exports = mongoose.model('Network', {
network_id:ObjectId,
location: String,
hostname: String,
device: String,
model: String,
ipAddress: [ipaddressSchema],
subnets: [subnetSchema],
iosVersion: String,
softwareImage: String,
serialNumber: String,
});
var ipaddressSchema = Schema ({
ipAddress: String,
type: String,
});
var subnetSchema = Schema ({
range: String,
type: String,
});
Controller:
var Network = require('../models/network');
module.exports.create = function (req, res) {
var network = new Network(req.body);
network.save(function (err, result) {
res.json(result);
});
}
module.exports.list = function (req, res) {
Network.find({}, function (err, results) {
res.json(results);
});
}
Postman Query:
Postman Result:
I would like:
{
"__v": 0,
"location": "London Office",
"hostname": "lon-asa-01",
"device": "Switch-MLS",
"model": "Cisco 3750",
"softwareImage": "1.2",
"serialNumber": "123456",
"_id": "5510495c1d40ef965d7d1cec",
"subnets":[
["range" : "10.0.100.0/24", "type" : "Client" ],
["range" : "10.0.101.0/24", "type" : "Server" ],
],
"ipAddress": [
["ipAddress" : "10.0.100.1", "type" : "Inside" ],
["ipAddress" : "10.0.101.254", "type" : "Outside" ],
]
}
Ok, here you go:
First of all, your schema should look like this:
var networkSchema = module.exports = mongoose.model('Network', {
network_id: ObjectId,
location: String,
hostname: String,
device: String,
model: String,
ipAddress: [{type: ObjectId, ref: 'IpadressModelName'}],
subnets: [{type: ObjectId, ref: 'SubnetModelName'}],
iosVersion: String,
softwareImage: String,
serialNumber: String,
});
In your controller you have to insert first the entities on which your network relies on so you will have an _id to provide to the network model as reference:
module.exports.create = function (req, res) {
var network = new Network(req.body);
var ipAddress = [],
ipIds = [];
req.body.ipAddress.forEach(function(ip){
ipAddress.push(new IpadressModelName(ip));
});
var subnets = [],
subnetsIds = [];
req.body.subnets.forEach(function(sn){
subnets.push(new SubnetModelName(sn));
});
IpadressModelName.create(ipAddress, function () {
// args[0] should be the error
if (args[0]) {
throw args[0]
}else{
for(var i=1; i<args.length; i++ )
ipIds.push(args[i]._id);
}
SubnetModelName.create(subnets, function () {
// args[0] should be the error
if (args[0]) {
throw args[0]
}else{
for(var i=1; i<args.length; i++ )
subnetsIds.push(args[i]._id);
}
network.ipAddress = ipIds;
network.subnets = subnetsIds;
network.save(function (err, result) {
res.json(result);
});
});
});
}
Finally post data as raw JSON:
{
"location": "London Office",
"hostname": "lon-asa-01",
"device": "Switch-MLS",
"model": "Cisco 3750",
"softwareImage": "1.2",
"serialNumber": "123456",
"subnets":[
{"range" : "10.0.100.0/24", "type" : "Client" },
{"range" : "10.0.101.0/24", "type" : "Server" }
],
"ipAddress": [
{"ipAddress" : "10.0.100.1", "type" : "Inside" },
{"ipAddress" : "10.0.101.254", "type" : "Outside" }
]
}
The code in this example is just for demonstrating a approach you can use and it is not conforming to the best practices.

Categories