I try to count property of one object inside another but get a wrong value: I want to count the object inside property of productInfo of order object which is 15 but my function return 46.
router.get("/product", isLoggedIn, function (req, res) {
products.find({}, function (err, products) {
if (err) {
console.log("ERROR!");
} else {
orders.find({
customerInfo: req.user
}, function (err, orders) {
if (err) {
console.log("ERROR!");
} else {
res.render("allProduct", {
data1: _.keys(orders[0].productInfo).length,//here object must counted!
data:products
});
}
});
}
});
});
and here are my models:
var mongoose = require("mongoose");
var order = new mongoose.Schema({
orderNo: Number,
customerInfo: [{
type: mongoose.Schema.Types.ObjectId,
ref: "User"
}],
productInfo: [{
type: mongoose.Schema.Types.ObjectId,
ref: "product"
},]
});
//EXPORT
module.exports = mongoose.model("order", order);
and:
var mongoose =require("mongoose");
var product = new mongoose.Schema({
productNo: Number,
productName: String,
productDes:String,
productPrice:Number,
});
//EXPORT
module.exports = mongoose.model("product",product);
I solve this issues with replace :
_.keys(orders[0].productInfo).length,
with:
orders[0].productInfo.length
Related
i am working on a mern project where i need to create an agenda that contains an attribute as array of appointments types.
in the nodejs api i am declaring a var typeRefs = [];
if a type is present in the types model i insert its ref in the previous array else i create the type and insert the new type ref in the previous array, finally i create the agenda doc based on the typeRefs array, but the array is empty outside the map function scope , inside the map function scope i can see the array values changing.
//agenda model
const agendaSchema = mongoose.Schema(
{
name: String,
types: [{ type: mongoose.Schema.Types.ObjectId, ref: "Type" }],
establishment: {
type: mongoose.Schema.Types.ObjectId,
ref: "Establishment",
},
template: { type: mongoose.Schema.Types.ObjectId, ref: "Template" },
isActive: { type: Boolean, default: true },
},
{ timestamps: true }
);
var Agenda = mongoose.model("Agenda", agendaSchema);
export default Agenda;
// types model
import mongoose from "mongoose";
const typeSchema = mongoose.Schema(
{
name: String,
duration: Number,
color: String,
online: { type: Boolean, default: true },
establishment: {
type: mongoose.Schema.Types.ObjectId,
ref: "Establishment",
},
},
{ timestamps: true }
);
var Type = mongoose.model("Type", typeSchema);
export default Type;
// api function for agenda creation
export const add = async (req, res) => {
var data = req.body;
try {
var typesRefs = [];
data.types.map((type) => {
Type.find({ name: type.text.toUpperCase() }, (err, res) => {
if (res.length === 0) {
const newType = new Type({
name: type.text.toUpperCase(),
establishment: data.establishment,
});
newType.save();
typesRefs = [...typesRefs, newType._id];
} else {
typesRefs = [...typesRefs, type._id];
}
});
});
console.log(typesRefs);
await Agenda.create({ ...data, types: typesRefs });
res.status(200).json({ message: "Agenda created successfully" });
} catch (error) {
console.log(error);
res.status(401).json({ message: "An error occured !" });
}
};
the trick is to use a for loop instead of map function.
export const add = async (req, res) => {
var data = req.body;
var typeRefs = [];
try {
for (let i = 0; i < data.types.length; i++) {
const typeExist = await Type.find({
name: data.types[i].text.toUpperCase(),
});
if (typeExist.length === 0) {
const newType = await Type.create({
name: data.types[i].text.toUpperCase(),
establishment: data.establishment,
});
typeRefs = [...typeRefs, newType._id];
} else {
typeRefs = [...typeRefs, data.types[i]._id];
}
}
console.log(typeRefs);
await Agenda.create({ ...data, types: typeRefs });
res.status(200).json({ message: "Agenda created successfully" });
} catch (error) {
console.log(error);
res.status(401).json({ message: "An error occured !" });
}
};
var mongoose = require("mongoose"),
campground = require("./models/campground"),
comment = require("./models/comment");
var data = [{
name: "Offside Lake",
image: "https://images.unsplash.com/photo-1504280390367-361c6d9f38f4?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60",
description: "Whatever evrr"
},
{
name: "Reality Check",
image: "https://images.unsplash.com/photo-1517824806704-9040b037703b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60",
description: "wabdiwyu"
},
{
name: "Wawu Land",
image: "https://images.unsplash.com/photo-1508873696983-2dfd5898f08b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60",
description: "Just be feeling Wawu"
}
];
var text = {
text: "Hullabaloo",
author: "Olalaa"
};
campground.comments = new Array();
function seedDB() {
campground.deleteMany({}, function(err) {
if (err) {
console.log(err);
} else {
console.log("removed");
data.forEach(function(camp) {
campground.create(camp, function(err, camp) {
if (err) {
console.log(err);
} else {
console.log("Successfully added");
comment.create(text, function(err, comment) {
if (err) {
console.log(err);
} else {
campground.comments.push(comment);
campground.save();
console.log("comment added");
}
});
}
});
});
}
});
}
I have two mongoose models campground and comment. Inside the campground schema, I have the comments associative array in the campground schema. I am trying to add comments to my comments array but I am getting the error - campground.save is not a function. Even tried campground.markModified("comment") then campground.save(), getting the same error
//my campground schema
var mongoose = require("mongoose");
var campSchema = new mongoose.Schema({
name: String,
image: String,
description: String,
comments: [{
type: mongoose.Schema.Types.ObjectId,
ref: "comment"
}]
});
module.exports = mongoose.model("Camp", campSchema);
//my comment schema
var mongoose = require("mongoose");
var commentSchema = mongoose.Schema({
text: String,
author: String
})
module.exports = mongoose.model("comment", commentSchema);
If I understand what you are trying to do, you are trying to create a campground and place the comments inside.
If that is so, then the code may look something like this (placed everything in one file):
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/test', {useNewUrlParser: true});
var data = [
{
name: "Offside Lake",
image: "https://images.unsplash.com/photo-1504280390367-361c6d9f38f4?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60",
description: "Whatever evrr"
}, {
name: "Reality Check",
image: "https://images.unsplash.com/photo-1517824806704-9040b037703b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60",
description: "wabdiwyu"
}, {
name: "Wawu Land",
image: "https://images.unsplash.com/photo-1508873696983-2dfd5898f08b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60",
description: "Just be feeling Wawu"
}
];
const comment = mongoose.model('comment', new mongoose.Schema({
text: String,
author: String
}));
const campground = mongoose.model('Camp', new mongoose.Schema({
name: String,
image: String,
description: String,
comments: [{
type: mongoose.Schema.Types.ObjectId,
ref: "comment"
}]
}));
var text = {
text: "Hullabaloo",
author: "Olalaa"
};
campground.deleteMany({}, function(error) {
if (error) {
console.error(error);
return;
}
console.log("Removed");
data.forEach(function(camp) {
campground.create(camp, function(error, newCamp) {
if (error) {
console.error(error);
return;
}
console.log("Successfully added");
comment.create(text, function(err, newComment) {
if (err) {
console.error(err);
return;
}
newCamp.comments.push(newComment);
newCamp.save();
console.log("Comment added");
})
});
})
})
The problem was due to the fact that you kept the same name throughout and that might have confused you a bit.
What you wanted to do was camp.comments.push(comment) camp.save() instead of campground.comments.push(comment) and campground.save() respectively.
As a friendly advice:
Switch to using promises instead of callbacks, you may set yourself up for what is known as Callback hell
As much as possible try not to rely on the closure nature of JavaScript and keep naming your variables the same throughout. That leads to problems like what you are experiencing now
I have a User model that contains an array of customers. I want to delete a specific customer based on the customer _id. From what I've read in the Mongoose docs, I should use Model.deleteOne to delete a single document.
Here is my attempt
User Schema (it's been shortened for brevity):
const mongoose = require('mongoose');
const UserSchema = new mongoose.Schema({
username: {
type: String,
default: ''
},
password: {
type: String,
default: '',
},
registerDate: {
type: Date,
default: Date.now()
},
customer: [{
name: {
type: String,
default: '',
},
email: {
type: String,
default: 'No email name found'
},
fleet: [{
unitNumber: {
type: String,
default: 'N/A',
}
}]
}]
});
module.exports = mongoose.model('User', UserSchema);
Here is a look at the route and controller:
const express = require('express');
const router = express.Router();
const customer_controller = require('../../controllers/customers');
router.delete('/customers/:custid', customer_controller.customer_remove);
module.exports = router;
And finally the controller:
exports.customer_remove = (req, res) => {
const { params } = req;
const { custid } = params;
User.deleteOne({ 'customer._id': custid }, (err) => {
if (err)
throw err;
else
console.log(custid, 'is deleted');
});
};
From what I thought, User.deleteOne({ 'customer.id': custid }) would find the customer _id matching the custid that is passed in via the req.params. When I test this route in Postman, it deletes the entire User collection that the customer is found in, instead of just deleting the customer. Can I get a nudge in the right direction? I feel like I am close here (or not lol).
deleteOne operates at the document level, so your code will delete the first User document that contains a customer element with a matching _id.
Instead, you want update the user document(s) to remove a specific element from the customer array field using $pull. To remove the customer from all users:
User.updateMany({}, { $pull: { customer: { _id: custid } } }, (err) => { ...
Using Mongoose you can do this:
model.findOneAndUpdate({ 'customer._id': custid }, {$pull: { $pull: {
customer: { _id: custid } }}, {new: true}).lean();
Removing subdocs.
Each sub document has an _id by default. Mongoose document arrays have a special id method for searching a document array to find a document with a given _id.
Visit: https://mongoosejs.com/docs/subdocs.html
parent.children.id(_id).remove();
Use async-await, may be that will work.
exports.customer_remove = async (req, res) => {
const { params } = req;
const { custid } = params;
try {
await User.deleteOne({ 'customer._id': custid });
console.log(custid, 'is deleted');
} catch (err) {
throw err;
}
};
var mongoose = require("mongoose");
var jobs = new mongoose.Schema({
jobNumber: Number,
jobField: String,
jobTitle: String,
jobCity: String,
jobArea: String,
jobAddress: String,
jobPhone: String,
jobInsurance: String,
jobSalary: Number,
jobAccommodation: String,
jobDescription: String,
author: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
username: String
},
created: {
type: Date,
default: Date.now
}
});
//EXPORT
module.exports = mongoose.model("jobs", jobs);
//SHOW OWNED JOBS
router.get("/myjobs", function (req, res) {
jobs.find({},function (err, myjobs) {
if (err) {
res.send(err);
} else {
res.render("filteredJobs", {
datas: myjobs
});
}
});
});
In this case I will get all the data but, how can I find by username or author._id?
You can use something like this:
router.get("/myjobs/:user", function (req, res) {
jobs.find({'author.username':user},function (err, myjobs) {
...
}
}
Hello can someone help me. I can't set mongoose model field
Here my institute.js model file
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var instituteSchema = new Schema({
name: {type: String, required: true},
idApi: {type: String, required: true},
country: {
type: Schema.ObjectId,
ref: 'Country'
},
created_at: {type: Date, default: Date.now}
}, {collection: 'qel_par_institute', versionKey: false});
instituteSchema.methods.findByIdApi = function (id, callback) {
return mongoose.model('Institute').findOne().where('idApi').equals(id).exec(callback);
}
instituteSchema.methods.findByCountry = function (id, callback) {
return mongoose.model('Institute').find().where('country.id').equals(id).exec(callback);
}
mongoose.model('Institute', instituteSchema);
There the part of sync.js Persisting works except i can't either manually set the country ref neither another field
var instituteApi = new instituteModel({
name: item.name,
idFromApi: item.id
});
if (typeof item.country.id !== 'undefined') {
var country = new countryModel();
country.findByIdApi(item.country.id, function(err, res) {
if (err)
console.log(err);
if (res) {
instituteApi.country = res._id; //setting this way doesn't work
}
})
}
instituteApi.save(function(err) {
if (err)
console.log('something went wrong while saving!');
});
Couldn't set it because async call. Switched callback to promise with Q module. Everything works as wanted