I am trying to save document in mongodb. Don't have any success.
JSON:
{
"ticketType": "Enquiry",
"type": "AA",
"subType": "BB",
"subSubType": "CC",
"misidnProfile": {
"serviceTypes": [
"Postpaid", "Prepaid"
],
"circles": [
"AA", "BB"
]
}
}
Mongoose Model :
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var misidnProfile = new Schema({
serviceTypes: [String],
circles: [String],
});
var taggingProfile = new Schema({
ticketType: {type:String, required: true},
type: {type:String, required: true},
subType: {type:String, required: true},
subSubType: {type:String, required: true},
misidnProfile: {misidnProfile},
});
module.exports = mongoose.model("TaggingProfile", taggingProfile);
Code for saving data:
module.exports.createTaggingProfile = function(req, res){
var taggingProfile = new TaggingProfile(req.body);
taggingProfile.save(function (err, tg) {
if(err){
return res.status(500).json({
title: 'An error occurred',
error: err
});
}
res.status(200).json({
message: 'Saved TaggingProfile',
obj: tg
});
});
};
It is saving taggingProfile but not subdocument msisdnProfile. I am not able to understand where is the problem?
EDIT:
Now it is saving. Thanks #Neil
While updating document, I am sending JSON as
{
"ticketType": "Enquiry",
"type": "AA",
"subType": "BB",
"subSubType": "CC",
"misidnProfile": {
"serviceTypes": [
"Postpaid", "Prepaid", "ABC","PQR"
],
"circles": [
"AA", "BB"
]
}
}
Strange thing is observed that when i am trying to find document by id, I am getting TaggingProfile object, But it don't have msisdnProfile value.
Check below code.
TaggingProfile.findById(req.params.id, function (err, tg) {
if (err) {
return res.status(500).json({
title: 'An error occurred',
error: err
});
}
if (!tg) {
return res.status(500).json({
title: 'No TaggingProfile Found!',
error: {message: 'Message not found'}
});
}
req.taggingProfile=tg;
if(tg.misidnProfile){
console.log("## tg.misidnProfile PRofile present");
} else {
console.log("## tg.misidnProfile Not present");
}
for(var p in req.body){
req.taggingProfile[p] = req.body[p];
}
req.taggingProfile.save(function (err, result) {
if (err) {
return res.status(500).json({
title: 'An error occurred',
error: err
});
}
res.status(200).json({
message: 'Updated message',
obj: result
});
});
});
Related
I have a some code:
const taskId: number = req.body.taskId;
const text: string = req.body.text;
const task = await db.tasks.findOneAndUpdate(
{ taskId },
{ $push: { comments: [{
commentId: await db.getId(`task.${taskId}.commentId`),
taskId,
// #ts-ignore
author: Number(req.session.userId),
text,
timestamp: Date.now()
}] } }
).catch(e => {
console.error(e);
return res.status(400).json({ errors: [{ msg: "UNKNOWN_ERROR" }] });
});
if (!task) return res.json({ errors: [{ location: "query", msg: "NOT_FOUND", param: "taskId" }] });
return res.json(task);
But I have out (I skipped other properties):
{
...,
comments: [{
"timestamp": 1595833609905,
"_id": "5f1e7d09c1e15d4c8e0b71fa",
"taskId": 2,
"author": 435214391,
"text": "haha test comment"
}]
}
In comment property "commentId" is undefined.. But if I use
console.log({
commentId: await db.getId(`task.${taskId}.commentId`),
taskId,
// #ts-ignore
author: Number(req.session.userId),
text,
timestamp: Date.now()
})
I see the "commentId" property. Why it not saves in database? (Mongoose)
Okey, this is win. Error has been found in imports:
import TaskResponseSchema from './TaskResponse';
import TaskCommentSchema from './TaskResponse';
But okey:
import TaskResponseSchema from './TaskResponse';
import TaskCommentSchema from './TaskComment';
I am using Mongoose npm module to manage mongodb.
This is schema of mongodb collection what I am going to update.
var UserSchema = new Schema({
username: {
type: String,
unique: true,
required: true
},
email: {
type: String,
unique: true,
required: true
},
cards: []
});
module.exports = mongoose.model('User', UserSchema);
inside post request, here req is request object of post request.
and res is response object.
User.findById(userID).exec(function (err, doc) {
let cardInfo = req.cardInfo
let cardIndex = req.cardIndex
doc["cards"][0] = cardInfo;
console.log(doc)
/* here I got right doc object as I requested
{
"_id": "59f3bdd488f912234fcf06ab",
"email": "test#gmail.com",
"username": "test",
"__v": 2,
"cards": [
{
"testNo": "42424242424242"
}
]
}
*/
doc.save(function (err) {
if (err) {
return res.json({
success: false,
msg: 'Card add error'
});
}
res.json({
success: true,
msg: 'Successful updated card.'
});
});
})
I got message 'Successful updated card.', but actually, It doesn't save.
How to solve it. Thanks.
The problem is that mongoose don't knwo your array is modified.
You can use 2 solutions :
markModified
This function will mark the embedded element as modified and force a resave of it.
It will tell mongoose to resave this element.
User.findById(userID).exec(function (err, doc) {
let cardInfo = req.cardInfo
let cardIndex = req.cardIndex
doc["cards"][0] = cardInfo;
console.log(doc)
/* here I got right doc object as I requested
{
"_id": "59f3bdd488f912234fcf06ab",
"email": "test#gmail.com",
"username": "test",
"__v": 2,
"cards": [
{
"testNo": "42424242424242"
}
]
}
*/
doc.markModified('cards');
doc.save(function (err) {
if (err) {
return res.json({
success: false,
msg: 'Card add error'
});
}
res.json({
success: true,
msg: 'Successful updated card.'
});
});
})
Use a full schema.
To avoid the markModified trick, you should describe the content of cards in your schema. This way mongoose will be able to determine if it needs to save the field or not.
Here is the way to declare your schema properly :
const CardSchema = new Schema({
testNo: String,
});
var UserSchema = new Schema({
username: {
type: String,
unique: true,
required: true
},
email: {
type: String,
unique: true,
required: true
},
cards: [CardSchema]
});
module.exports = mongoose.model('User', UserSchema);
This way, mongoose will be able to detect if a value inside cards changed and save only the modified item.
If you can do it (static schema), this is clearly the good way to do it.
If you just want to update cards based on cardIndex:
User.update({_id: userID}, {'$set': {
'cards.cardIndex': cardInfo
}}, function(err) {
//code
}
Thanks for all answers.
I find this solution in addition.
doc["cards"].set(cardIndex, cardInfo)
Cheers!
I'm having an issue trying to get data from my backend express api. I'm using mongodb and mongoose too. Here's my code:
Code:
const show = (req, res) => {
const product = {}
product.array = new Array()
console.log(req.cart.product[1])
for (let i = 0; i < req.cart.product.length; i++) {
Product.find({_id: ObjectId(req.cart.product[i])},function(err,products){
if (err) {
res.sendStatus(500)
} else {
product.array.push(products)
console.log(product.array)
}
})
}
req.cart.product = product.array
res.json({
cart: req.cart.toJSON({ virtuals: true, user: req.user })
})
}
Console.logs:
[ [ { _id: 5952b57ea52d092b8d34c6b0,
name: 'test00000',
price: 0,
description: 'test',
__v: 0 } ] ]
[ [ { _id: 5952b57ea52d092b8d34c6b0,
name: 'test00000',
price: 0,
description: 'test',
__v: 0 } ],
[ { _id: 5952b57ea52d092b8d34c6b0,
name: 'test00000',
price: 0,
description: 'test',
__v: 0 } ] ]
URL Response:
{
"cart": {
"_id": "5953b153d2108941d15a7fe9",
"updatedAt": "2017-06-28T13:38:27.406Z",
"createdAt": "2017-06-28T13:38:27.406Z",
"owner": "595153ad6f18427ef38c416b",
"__v": 0,
"product": [],
"id": "5953b153d2108941d15a7fe9",
"editable": false
}
}
Everything in the console logs is what I want to return in the products array for my response but it won't populate the array when I push it. Any thoughts?
You are trying to call asynchronous code, (e.g. Db query) inside the synchronous code (e.g. for-loop). That's why it returns data to client once it gets the data for the first time. You can async or promise.all to solve the problem.
var async = require('async')
const show = (req, res) => {
const product = {}
product.array = new Array()
console.log(req.cart.product[1])
async.each(req.cart.product, function(id, cb){
Product.find({_id: ObjectId(id)},function(err,products){
if (err) {
cb(err)
} else {
product.array.push(products)
console.log(product.array)
cb()
}
})
}, function(err){
if (err) {
return res.sendStatus(500)
} else {
req.cart.product = product.array
return res.json({
cart: req.cart.toJSON({ virtuals: true, user: req.user })
})
}
})
}
Promise based solution:
const show = (req, res) => {
const product = {}
product.array = new Array()
console.log(req.cart.product[1])
const promises = []
req.cart.product.forEach(function(id){
promises.push(Product.find({_id: ObjectId(req.cart.product[i])}))
})
Promise.all(req.cart.product.map(function(id) {
return Product.find({_id: ObjectId(id)})
})).then(function(products){
req.cart.product = product.array
return res.json({
cart: req.cart.toJSON({ virtuals: true, user: req.user })
})
}).catch(function(err){
return res.sendStatus(500)
})
}
I'm trying to remove an object from an array in a document using mongoose.
The Schema is the following:
var diveSchema = new Schema({
//irrelevant fields
divers: [{
user: { type: Schema.Types.ObjectId, ref: 'User', required: true },
meetingLocation: { type: String, enum: ['carpool', 'onSite'], required: true },
dives: Number,
exercise: { type: Schema.Types.ObjectId, ref: 'Exercise' },
}]
});
a possible entry can be
{
//irrelevant fields
"divers": [
{
"_id": "012345678",
"user": "123456789",
"meetingLocation": "carpool",
"exercise": "34567890",
},
{
"_id": "012345679",
"user": "123456780",
"meetingLocation": "onSite",
"exercise": "34567890",
}
]
}
Say I want to remove the entry where user is 123456789 (note I do not know the _id at this point).
How do I do this correctly?
I tried the following:
var diveId = "myDiveId";
var userIdToRemove = "123456789"
Dive.findOne({ _id: diveId }).then(function(dive) {
dive.divers.pull({ user: userIdToRemove });
dive.save().then(function(dive) {
//do something smart
});
});
This yieled no change in the document.
I also tried
Dive.update({ _id: diveId }, { "$pull": { "divers": { "diver._id": new ObjectId(userIdToRemove) } } }, { safe: true }, function(err, obj) {
//do something smart
});
With this I got as result that the entire divers array was emptied for the given dive.
What about this?
Dive.update({ _id: diveId }, { "$pull": { "divers": { "user": userIdToRemove } }}, { safe: true, multi:true }, function(err, obj) {
//do something smart
});
I solve this problem using this code-
await Album.findOneAndUpdate(
{ _id: albumId },
{ $pull: { images: { _id: imageId } } },
{ safe: true, multi: false }
);
return res.status(200).json({ message: "Album Deleted Successfully" });
Try this
Dive.update({ _id: diveId },{"$pull": { "drivers": {"user": "123456789"}}})
Try this async code
var diveId = "myDiveId";
var userIdToRemove = "123456789"
const dive=await Dive.findOne({ _id: diveId })
await dive.divers.pull({ user: userIdToRemove });
await dive.save();
Use this with try/catch:
await Group.updateOne(
{ _id: groupId },
{ $pull: { members: {id: memberId }}}
);
i need to push data in nested subdocument array:
this is my Json:
[
{
_id: "56cbe9727bab33a413216dd4",
company_name: "Star",
__v: 0,
created_at: "2016-02-23T05:09:06.754Z",
plan: [
{
plan_name: "Mediclassic",
plan_type: "Individual",
_id: "56cbe9727bab33a413216dd5",
created_at: "2016-02-23T05:09:06.756Z",
rate_card: [
{
zone: "zone-2",
suminsured: 150000,
premium: 2874,
size: "1A",
_id: "56cbe9727bab33a413216dd6",
benefits: {
hospitals: true,
copay: true,
cashless_hospital: true,
existing_disease_cover: true
},
age: {
min: "5M",
max: 35
}
}
]
}
]
}
]
I need to push my data in rate_card, i have tried something but its not working
below is my code:
AngularController.js
$scope.RateCardCreateAction = function(){
$scope.params = $routeParams.id;
console.log($scope.insurance.plan.rate_card);
$http.put('/auth/insurance-list/plan/new/rate_card/' + $scope.params, $scope.insurance.plan.rate_card).success(function(response){
console.log(response);
refresh();
});
};
mainRoutes.js
// New Rate Card
router.put('/secure/insurance-list/plan/new/rate_card/:id', function(req, res){
var id = req.params.id;
Insurance.update({'plan._id':id}, {$push :
{
'rate_card' : {
'zone' : req.body.zone,
'suminsured' : req.body.suminsured,
'premium' : req.body.premium,
'size' : req.body.size,
'age' : {
'min' : req.body.age.min,
'max' : req.body.age.max
},
'benefits' : {
'hospitals' : req.body.benefits.hospitals,
'cashless_hospital' : req.body.benefits.cashless_hospital,
'copay' : req.body.benefits.copay,
'existing_disease_cover' : req.body.benefits.existing_disease_cover
}
}
}
}, {upsert: true}, function(err, docs){
res.json(docs);
console.log(docs);
});
});
Here i need to push data to rate_card, but data is not storing in subdocument array, here am getting plan id and trying to push but is not working
in server response am getting this { ok: 0, n: 0, nModified: 0 }
Try this, i hope this will help you
router.put('/secure/insurance-list/plan/new/rate_card/:id/:id2', function(req, res){
var id = req.params.id;
var id2 = req.params.id2;
Insurance.update({_id:id, 'plan._id':id2}, {$push :
{'plan.$.rate_card' : req.body}
}, {upsert: true}, function(err, docs){
res.json(docs);
console.log(docs);
});
});
If somehow your inserted value is not present then it would be great to use $addToSet.
var updateArr = {
'roomUsers':{
userId:req.session.userInfo._id,
requestDate:Date.now(),
status:1
}
};
roomInfo.findOneAndUpdate({_id:roomId}, {$addToSet:updateArr}, (err, result) => {
if (!err && result) {
res.send({
status:true
});
}
else{
res.send({
status:false
});
}
});
I got it done using below update query:
db.insurance.updateOne(
{
_id: ObjectId('60659595afcb710627e3fad7')
},
{
$push: {
"plan.$[element].rate_card": {
$each: [
{ _id: ObjectId('6062bd90c5a1d66fdd2c91bc'), premium: 2874, size: "1A" },
{ _id: ObjectId('6062bd90c5a1d66fdd2c91bc'), premium: 2874, size: "1A" }]
}
}
},
{
arrayFilters: [{ "element._id": ObjectId('6065a35ee1e5f1153504e861') }]
}
);
In $each you need to add your array of object.
element._id is your subdocument id (above case is plan _id).