Getting [object Object] again but doesn't seem to be model issue - mongodb

I am trying to figure out how to access the author.id for a model when using a for loop with swig/twig. All of the others print out just fine but the ap.author.id is the issue I have tried ap.author.id, ap.author.id.type and ap.author.id.ref just hoping it was like my issue before seen HERE but it seems it is not model related far as I can tell. Also when I console.log out aps it shows all the documents and the path that makes sense would be ap.author.id. I am out of ideas, what am I missing?
Loop:
{% for ap in aps %}
<tr>
<td>{{ap.name}}</td>
<td>{{ap.manufacturer}}</td>
<td>{{ap.model}}</td>
<td>{{ap.type}}</td>
<td>{{ap.notes}}</td>
<td>{{ap.author.id}}</td>
</tr>
{% endfor %}
Model:
var accessPointsSchema = new Schema({
name: {type: String},
type: {type: String},
manufacturer: {type: String},
model: {type: String},
IPAdress: {type: String},
MACAdress: {type: String},
range: {type: Number()},
bands: {type: String},
channel: {type: Number},
dateBought: {type: Date},
PoE: {type: Boolean},
assetNumber: {type: Number},
warrantyExpiration: {type: Date},
location: {type: String},
notes: {type: String},
author: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
email: String
}
});

When you console.log author.id you get back an object that will contain the ID needed but you need to access it by doing author._id otherwise you will get the [object Object] error because it is trying to output an object into a string spot.

Related

Update field in another schema with post hook mongoose

I have that schemas:
var schema = new Schema({
number: {type: Number},
subtotal: {type: Float, required: true},
quantity: {type: Number, required: true},
prodprov: {type: Schema.Types.ObjectId, ref: 'ProdProv'},
order: {type: Schema.Types.ObjectId, ref: 'Order'}
});
module.exports = mongoose.model('OrderDetail', schema);
and
var schema = new Schema({
name: {type: String, required: true},
price: {type: Float, required: true},
idProvider: {type: Schema.Types.ObjectId, ref: 'Provider'},
idProduct: {type: Schema.Types.ObjectId, ref: 'Product'},
description: {type: String},
quantitySold: {type: Number}
});
module.exports = mongoose.model('ProdProv', schema);
I need to update field "quantitySold" when a post.save happens in order-detail, i've tried this:
schema.post('save', function(next){
//But this point I can't find the prodprov to update field
})
How I can do this?
Thank you.
Thank you #mjim, but that´s code not works. I've modify the code and works! this is my solution:
schema.post('save', function(doc){
var prod = ProdProv.findById(this.prodprov).exec().then((pp) => {
pp.quantitySold += this.quantity;
pp.save();
});
});
I would suggest:
var ProdProv = require('./ProdProv');
var schema = new Schema({
number: {type: Number},
subtotal: {type: Float, required: true},
quantity: {type: Number, required: true},
prodprov: {type: Schema.Types.ObjectId, ref: 'ProdProv'},
order: {type: Schema.Types.ObjectId, ref: 'Order'}
});
schema.post('save', async function(doc){
var prod = await ProdProv.findById(doc.prodprov);
prod.quantitySold = doc.quantity;
prod.save()
});
module.exports = mongoose.model('OrderDetail', schema);

Mongoose delete nested subdocuments and documents

I have:
let userSchema = mongoose.Schema({
email: {type: String, required: true, unique: true},
passwordHash: {type: String, required: true},
fullName: {type: String, required: true},
salt: {type: String, required: true},
ads: [{type: ObjectId, ref: 'Ad'}],
roles: [{type: String}]
}
let adSchema = mongoose.Schema({
author: {type: ObjectId, ref: 'User'},
title: {type: String, required: true},
category: {type: ObjectId, ref: 'Category', required: true},
town: {type: ObjectId, ref: 'Town', required: true},
}
);
let categorySchema = mongoose.Schema({
name: {type: String, required: true, unique: true},
ads: [{type: ObjectId, ref: 'Ad'}]
}
);
let townSchema = mongoose.Schema({
name: {type: String, required: true, unique: true},
ads: [{type: ObjectId, ref: 'Ad'}]
}
);
I want to find for example town by id and remove all ads in it(and ofcourse to remove the ads from their categories and authors).How can i do that?
I would suggest bulk getting the array of object Ids and using it like this:
Ad.remove({_id: {$in: Ad_ids_array}}, function(){...}); // and so on
You can add a pre-remove hook in the ad schema definition like this:
adSchema.pre('remove', function(next) {
let lethis = this;
// Pull ad out of all the Category docs that reference the removed ad.
this.model('Category').update({}, { $pull: {ads: lethis._id}}, { safe: true }, next);
// Pull ad out of all the User docs that reference the removed ad.
this.model('User').update({}, { $pull: {ads: lethis._id}}, { safe: true }, next);
});
This will remove the ad from the categories and users that have it in their ads array.

How do I set a value to be fixed aka un-updateable

I'm making a database for beavers, however some properties should be unchangeable such as the birth date or the location where it was first seen.
How do I implement this? Is there a mongoose schema property for this? Or do I do it with JS?
Example of the schema:
let beaverSchema = new Schema({
id: {type: String, required: true, unique: true},
birthDate: {type: Date},
locationSpotted: {type: String},
firstSeen: {type: Date},
status: {type: String, default: "Alive"},
sex: {type: String}
})

Referencing multiple collections within MongoDB

I have three collections in my Database: Apps, Reviews, and Users.
Apps will have multiple reviews, reviews will have one user, and users will have multiple reviews.
I do need them all tied together and am struggling. I have been able to attach reviews to users (and vice versa), but I am unable to attach the reviews to the apps. I was thinking this action needs to happen on the POST to the database for a review.
I do have the appId required (and it's stored within the review body), but I am unable to correctly identify and update the correct collection (applications) in the database. I seem to be spinning myself in circles over this.
Basically, I need to reference both the Application the review is for, and the User who reviewed when a review is posted. I do have all models "correctly" referencing the other collections (as you demo'd with your messages and users components).
Would anyone be able to point me in the right direction? Here is my code for the POST so far.
// SAVE A REVIEW TO DATABASE
router.post('/', function(req, res, next) {
var decoded = jwt.decode(req.query.token);
User.findById(decoded.user._id, function(err, doc) {
if (err) {
return res.status(404).json({
title: 'An error occurred',
error: err
});
}
var review = new Review({
content: req.body.content,
rating: req.body.rating,
app: req.body.appId,
user: doc
})
Application.findById(req.body.appId, function(err, doc) {
if (err) {
return res.status(404).json({
title: 'An error occurred',
error: err
});
}
review.save(function(err, result) {
if (err) {
return res.status(404).json({
title: 'An error occurred',
error: err
});
}
review.update(function(err, result) {
if (err) {
return res.status(404).json({
title: 'An error occurred',
error: err
});
}
doc.reviews.push(result);
doc.save();
res.status(201).json({
message: 'Saved review',
obj: result
});
});
});
});
MODELS:
Review Model:
var schema = new Schema({
content: {type: String, required: true},
rating: {type: Number},
dateCreated: {type: String},
app: {type: Schema.Types.ObjectId, ref: 'Application'},
user: {type: Schema.Types.ObjectId, ref: 'User'}
});
Application Model:
var schema = new Schema({
name: {type: String, required: true},
description: {type: String},
reviews: [{type: Schema.Types.ObjectId, ref: 'Review'}],
})
User Model:
var schema = new Schema({
firstName: {type: String, required: true},
lastName: {type: String, required: true},
password: {type: String, required: true},
passwordConfirm: {type: String, required: true},
email: {type: String, required: true, unique: true},
reviews: [{type: Schema.Types.ObjectId, ref: 'Review'}]
});
Perhaps I am going the way wrong way about this, but I seem to be pretty lost.
Thank you everyone in advance.

How to write a Mongoose query for items whose IDs are not in an array

I have two models: Event and People.
schemas.event = new mongoose.Schema({
eventId: Number,
name: {type: String},
size: Number,
location: {type: String},
date: {type: Date},
people: [{type: mongoose.Schema.Types.ObjectId, ref: models.Person}],
note: {type: String}
});
and People
schemas.person = new mongoose.Schema({
firstname: {type: String},
lastname: {type: String},
age: Number,
email: {type: String},
gender: {type: String}
});
Given a certain event, I want to do a Query using Mongoose, to find all the people not already registered for this event.
Something like
models.Person.find({not in event.people});
The tricky thing for me is, that event.people is not an array of IDs, but rather it is an array of Objects that look like
[
{
"$oid": "558ced061d35bd072e7b5825"
},
{
"$oid": "558ced061d35bd072e7b58a0"
},
{
"$oid": "558ced061d35bd072e7b58c6"
}
],
Is there any way to simply make this query?
Firstly, you need to create an array of the ObjectId's by using the native JavaScript method map() which creates a new array with the results of calling a provided function on every element in this array:
var mongoose = require("mongoose");
var arr = event.people.map(function(item){ return mongoose.Types.ObjectId(item["$oid"])});
You can then query the collection using that as the $nin operator expression:
models.Person.find({"_id": { "$nin": arr}}).exec(callback);
Look into the following operators:
$not - http://docs.mongodb.org/manual/reference/operator/query/not/
$in - http://docs.mongodb.org/manual/reference/operator/query/in/
$nin - http://docs.mongodb.org/manual/reference/operator/query/nin/