I'm trying to send an object to an array in my model, but every time I do, the array is still empty.
I pass the object to the backend and it arrives here:
var addFavoriteRecipe = function(req, res){
if(req.user){
console.log(req.body);
userModel.User.find({_id: req.user._id}, {$push :{favoriteRecipes: {name: req.body.alias, _id: req.body._id}}}, function(err){
if(err){
res.send(err);
}else{
res.send("success!");
}
});
}else{
var sendBackError = {err: true, message: "You are not logged in."}
res.send(sendBackError);
}
}
The console log on req.body shows all the data I passed back, and has the two fields I'm trying to push into the array.
Here is my Model:
var userSchema = mongoose.Schema({
username: {
type: String,
required: true,
unique: true
},
email: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
},
friendsList: {
type: Array,
},
favoriteRecipes: {
type: Array,
}
});
I've toyed around with the code, but I really am lost as to where I should go from here. I want to think it's something on my model, but I'm not entirely sure.
You can define your model for an array of objects, either this way:
favoriteRecipes: [{
_id: ObjectId,
name: String
}]
or
favoriteRecipes: { type : Array , "default" : [] }
but, The problem seems to be here:
userModel.User.find(
{_id: req.user._id},
{ $push : {favoriteRecipes: {name: req.body.alias, _id: req.body._id}}},
function(err){
if(err){
res.send(err);
}else{
res.send("success!");
}
});
You are using find you need to change it to update:
userModel.User.update(
{_id: req.user._id},
{ $push : { favoriteRecipes: {name: req.body.alias, _id: req.body._id}}},
function(err){
if(err){
res.send(err);
}else{
res.send("success!");
}
});
Related
var ItemSchema = new Schema({
item: {type: String, required: false},
ts: {type: String, required: true},
selldate: {type: Number, required: false},
replaced: [ReplaceSchema]
});
var ProductSchema = new Schema({
title: {type: String, required: true, trim: true}, //name of the products
artNo: {type: Number, required: true},
catId: {type: String, required: true},
productType: {type: String, required: true}, //physical, textbased or downloadable product | can be 'dl', 'txt', 'phy'
tid: {type: String, required: false}, //only needed for physical products for providing a tid
minItems: {type: Number, required: true},
ts: {type: Number, required: true}, // when was the product online
buyCount: {type: Number, required: true}, // baught how many times
description: {type: String}, //more about the product
price: {type: Number, required: true}, // how much?
discounts: [DiscountSchema], // discount objects
items: [ItemSchema],
images: [], // fullsize images of the product
thumbnails: [], // small preview images of the product
// isPublic: {type: Boolean, required: true}, // if product should be published or not
itemCount: {type: Number, required: false} // how many items exists on the product
});
var CategorySchema = new Schema({
name: {type: String, required: true},
ts: {type: Number, required: true},
products: [ProductSchema]
});
So you see its: Category -> products[] -> items[]
I want to update the Objects in items array in the database and set (at this time undefined field "selldate".
My code snippet for this looks like this:
Category.getProductOfCategory(productId, function(err, boughtProduct) {
if (err) {
res.send({
status: false,
data: err
})
} else {
// console.log('BoughtProduct: ', boughtProduct.products[0])
var bought = boughtProduct.products[0];
// console.log('theItem: ', bought.items.id(item._id));
bought.items.id(item._id).selldate = Date.now();
bought.save(function(err, results) {
if (err) {
res.send({
status: false,
data: err
})
} else {
// i is increased because we need it on line 5
// console.log('itemerr', err)
console.log('saved', results);
j++;
// the next() function is called when you
// want to move to the next item in the array
next();
}
});
}
});
But nothing is happening in the database. Im getting No errors but "results" is just undefined.
Can you please help me?
Update:
I have a solution BUT it works only on executing it once.. after that, its nothing happening again...
The Code:
Category.findById(catId, function (err, data) {
if (err) console.log(err);
data.products.id(productId).items.id(item._id).selldate = Date.now();
data.save(function (err, result) {
if (err) console.log(err);
j++;
next();
});
});
i have posted a sample program containing documents & sub-documents.
Kindly check this and let me know if you need additional information
Schema
const PostSchema = new Schema({
title : String
});
const HomeSchema = new Schema({
"name" : {
type : String,
required : true
},
"city" : {
type : String,
required : true
},
post : [PostSchema]
});
To Save document and subdocument
const cat = new HomeModel({
name: "tiger",
city : "africa",
post : [{
"title" : "tiger post"
}]
});
cat.save((user) => {
console.log("saved");
console.log(user);
})
.catch((err)=>{
console.log("err");
console.log(err);
});
To update document
HomeModel.update({name : "tiger"},{city : "china123"})
.then((home)=>{
console.log("updated");
console.log(home);
})
.catch((error) => {
console.log("error");
console.log(error);
});
To add new subdocument
HomeModel.findOne({name : "tiger"})
.then((home) => {
console.log("findone")
console.log(home);
home.post.push({"title" : "monkey"});
home.save();
})
.catch((err)=>{
console.log("error");
});
To update existing subdocument
method:1
HomeModel.findOne({name : "tiger"})
.then((home) => {
console.log("findone")
const tes=home.post.id("5a3fe65546c99208b8cc75b1");
tes.set({"title" : "it workssdfg"});
home.save();
})
.catch((err)=>{
console.log("error");
});
To find parent document using sub-document id
HomeModel.findOne({"post._id" : "5a3fe65546c99208b8cc75b1"})
.then((home) => {
console.log("findone")
console.log(home);
})
.catch((err)=>{
console.log("error");
});
Here is a relevant part of my Schema, where I'll make reservations to a "space":
var spaceSchema = new mongoose.Schema({
spaceName: String,
scheduledDates: [{
scheduledDates: String,
author: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
username: String
}
}]
});
Author should be the current user that's logged in. Here is my route to update those fields:
router.put('/:space_id/schedule', function(req, res) {
Space.findByIdAndUpdate(req.params.space_id, {
'$push': { 'scheduledDates': req.body.space, 'author': req.user._id }
}, { "new": true, "upsert": true }, function(err, space) {
if (err) {
console.log(err);
} else {
console.log(req.body.space);
}
});
});
I can't access "author" correctly, because it's inside the array. What can I do to update this array, adding a new date and user to make the reservation?
Thank you
UPDATE
I tried to use "_id" instead of "id" in my property but got the same result. It seems like it's ignoring the "author" field, and only saving "scheduledDates"
So the schema was like this:
scheduledDates: [{
scheduledDates: String,
author: {
_id: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
username: String
}
}]
And then in my route, I changed what I was 'pushing':
'$push': { 'scheduledDates': req.body.space, 'author._id': req.user._id }
UPDATED 2
Changed the way I was getting the object to push:
'$push': {
'scheduledDates': {
'scheduledDates': req.body.space,
'author': { _id: req.user._id, username: req.user.username }
}
}
Now I'm getting the following error:
message: 'Cast to string failed for value "{ scheduledDates: \'04/11/2017\' }" at path "scheduledDates"',
name: 'CastError',
stringValue: '"{ scheduledDates: \'04/11/2017\' }"',
kind: 'string',
value: [Object],
path: 'scheduledDates',
reason: undefined } } }
I have a mongodb object, the model is given below, I want to add contents to the existing array
var UsersSchema = new Schema({
name: {
type: String,
required: true
},
EmpId: {
type: string,
required: true
},
feed:[{
status: {
type: String
},
comments: {
type: String
},
posted_date: {
type: Date,
default : Date.now
}
}]
});
using a PUT or POST can I add contents to an existing document's feed array.please check the below code
router.put('/api/user1', function(request, response){
Model.findById(request.body._id, function(err, user){
console.log(user.feed);
if(err){
response.status(404).send(err);
}
else {
user.update(
{_id: user._id },
{ $addToSet:
{ feed: user.feed }})
}
})
});
You should use $push to add to an array in Mongo after you find your document.
user.update(
{_id: user._id },
{ $push:
{ feed: user.feed }
})
Try:
user.update({_id: user.id}, {$addToSet: {feed: {$each: user.feed}}});
If you use $addToSet or $push without $each it will push the entire array onto the array in mongo, not each entry.
Forgive me as I'm pretty new to Mongoose and MEAN in general.
I am curious if an if statement like this would work to prevent a user from pushing themselves into an array twice.
Right now I'm using ng-hide to hide the 'attend' button, but I'd like to learn of a way to prevent it altogether in mongoose.
export function attending(req: express.Request, res: express.Response, next: Function){
if(req.params.id.attending.indexOf(req['payload']._id) !== -1) {
Event.update({_id: req.params.id}, {$push: {'attending': req['payload']._id }, $inc: {numGuests: -1}}, (err)=> {
if (err) return next (err)
User.update({user}, {$push: {'attending': event}}, (err)=> {
if(err) return next (err);
res.json({message: "You're In!"});
})
});
}
}
Here is the model
let eventSchema = new mongoose.Schema({
title: {type: String, required: true},
name:{type: String, required: true},
eventAddress: { type: String, required: true},
dateCreated: {type: Number},
eventCreator: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
attending: [{ type: mongoose.Schema.Types.ObjectId, ref: 'User'}]
});
Thanks for any suggestions!
I have this code:
router.post('/setsuggestions', function(req, res, next){
if(!req.body.username || !req.body.challengessuggestions){
return res.status(400).json({message: challengessuggestions});
}
var query = { username: req.body.username };
/*User.findOneAndUpdate(query, { challengessuggestions: req.body.challengessuggestions }, callback = function(response){
res.json(response);
});*/
/*
User.findOneAndUpdate(
query,
{$push: {"challengessuggestions": {$oid: req.body.challengessuggestions}}},
callback = function(response) {
res.json(response);
}
);*/
User.findOneAndUpdate(
query,
{$push: {challengessuggestions: req.body.challengessuggestions}},
{safe: true, upsert: true},
function(err, model) {
res.json(err);
}
);
});
When I postman like this:
I get the following error:
{ "name": "MongoError", "message": "exception: The field
'challengessuggestions' must be an array but is of type OID in
document {_id: ObjectId('56263b910d1a2f1f0077ffae')}", "errmsg":
"exception: The field 'challengessuggestions' must be an array but is
of type OID in document {_id: ObjectId('56263b910d1a2f1f0077ffae')}",
"code": 16837, "ok": 0 }
This is the schema definition of AppUser:
var UserSchema = new mongoose.Schema({
username: { type: String, lowercase: true, unique: true },
firstname: { type: String},
lastname: { type: String},
difficulty: { type: String},
isstudent: { type: Boolean },
haschildren: { type: Boolean},
gender: { type: String },
email: { type: String, unique: true},
birthdate: String,
isdoingchallenges: { type: Boolean },
challengescompleted: [{ type: ObjectId, ref: 'Challenge' }],
currentchallenge: { type: ObjectId, ref: 'Challenge' },
challengessuggestions: [{ type: ObjectId, ref: 'Challenge' }],
hash: String,
salt: String
});
This is the schema definiton of challenge:
var Challengeschema = new mongoose.Schema({
name: { type: String, initial: true, required: true, index: true },
image: { type: Array },
difficulty: { type: String },
studentfriendly: { type: Boolean },
childfriendly: { type: Boolean },
description: { type: String }
});
I'm sending this in the function that calls the api:
Object {_id: "5631423f8c5ba50300f2b4f6", difficulty: "medium", name:
"Probeer 1 van onze recepten.", __v: 0, childfriendly: true…}
This gives me following error:
D:\Stijn\Documenten\EVA-project-Groep-6\Api\node_modules\mongoose\lib\schema\obj
ectid.js:134
throw new CastError('ObjectId', value, this.path);
^ Error
at MongooseError.CastError (D:\Stijn\Documenten\EVA-project-Groep-6\Api\node
_modules\mongoose\lib\error\cast.js:18:16)
at ObjectId.cast (D:\Stijn\Documenten\EVA-project-Groep-6\Api\node_modules\m
ongoose\lib\schema\objectid.js:134:13)
at Array.MongooseArray.mixin._cast (D:\Stijn\Documenten\EVA-project-Groep-6\
Api\node_modules\mongoose\lib\types\array.js:124:32)
at Array.MongooseArray.mixin._mapCast (D:\Stijn\Documenten\EVA-project-Groep
-6\Api\node_modules\mongoose\lib\types\array.js:295:17)
at Object.map (native)
at Array.MongooseArray.mixin.push (D:\Stijn\Documenten\EVA-project-Groep-6\A
pi\node_modules\mongoose\lib\types\array.js:308:25)
at Query. (D:\Stijn\Documenten\EVA-project-Groep-6\Api\routes\ind ex.js:144:44)
at D:\Stijn\Documenten\EVA-project-Groep-6\Api\node_modules\mongoose\node_mo
dules\kareem\index.js:177:19
at D:\Stijn\Documenten\EVA-project-Groep-6\Api\node_modules\mongoose\node_mo
dules\kareem\index.js:109:16
at doNTCallback0 (node.js:408:9)
at process._tickCallback (node.js:337:13) 29 Oct 22:05:38 - [nodemon] app crashed - waiting for file changes before starti ng...
How do I solve this?
Query the User user using findOne() first and use the first found document that's passed to the callback to save the embedded documents with:
router.post('/setsuggestions', function(req, res, next){
if(!req.body.username || !req.body.challengessuggestions){
return res.status(400).json({message: challengessuggestions});
}
var query = { username: req.body.username };
User.findOne(query, function (err, user){
if (err) //throw ...
if (user) {
if (user.challengessuggestions && user.challengessuggestions.length) {
user.challengessuggestions.push(req.body.challengessuggestions);
}
else {
user.challengessuggestions = [req.body.challengessuggestions];
}
// save changes
user.save(function (err) {
if (!err) {
// done ...
}
});
}
});
);