How to use populate method with MongoDB in Node.js? - javascript

I have the following code:
const Order = require('../../models/order');
const Product = require('../../models/product');
Order.find({}, '_id product quantity', function(err, result) {
if (result) {
const response = {
count: result.length,
createdOrder: result.map(function(order) {
return {
_id: order._id,
productId: order.product,
quantity: order.quantity,
request: {
type: 'GET',
url: 'http://localhost:3000/orders/' + order._id
}
}
})
};
res.status(200).json(response);
} else if (err) {
console.log(err);
res.status(404).json({
error: err
});
}
});
How to use populate method to give more information about the product in the above syntax?

In your Order Schema you should set up a ref:
const mongoose = require('mongoose');
const orderSchema = mongoose.Schema({
// ...,
product: { type: mongoose.Schema.Types.ObjectId, ref: 'Product' }
});
module.exports = mongoose.model('Order', orderSchema);
Populate with product:
Order.find({})
.populate('product')
.exec()
.then(document => {
// handle the document...
});
Hope this helps!

Order.find({}, '_id product quantity', function (err, result) {
if (result) {
const response = {
count: result.length,
createdOrder: result.map(function (order) {
return {
_id: order._id,
productId: order.product,
quantity: order.quantity,
request: {
type: 'GET',
url: 'http://localhost:3000/orders/' + order._id
}
}
})
};
res.status(200).json(response);
}
else if (err) {
console.log(err);
res.status(404).json(
{
error: err
});
}
}).populate('product', '_id name price');
The populate method can be used in javascript syntax like the above.

Related

Mongoose Database populate issue

This is the code
app.get("/cart", checkAuthentication, function (req, res) {
Orders.find({ user: req.user._id })
.populate('user')
.populate('order')
.exec((err, orders) => {
console.log(orders);
if (err) {
console.log("ERROR /cart :\n" + err);
res.redirect("/");
} else {
const OrderList = [];
orders.forEach((order) => {
const obj = {
order: order.order,
id: order._id
}
OrderList.push(obj);
});
var sum=0
OrderList.forEach(function(item){
sum += item.order.price
});
req.session.sum = sum;
req.session.orders = OrderList;
res.render("cart", { itemList: OrderList, login: true, name: req.user.name });
// res.render("cart", { itemList: OrderList, login: false, name: "abc" });
}
});
});
This is order model =>
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const orderSchema = new Schema({
user: { type: Schema.Types.ObjectId, ref: "User" },
order: { type: Schema.Types.ObjectId, ref: "SellingItem" },
date: { type: Date, default: Date.now }
});
module.exports = mongoose.model("Orders", orderSchema);
THIS IS THE ERROR
ERROR(null)
This is the github link for my repo - https://github.com/Paras0750/Bakery_Website/
I am trying to populate orders field but it is showing null.
You are importing csv file with _id value. It will become string in the database instead of ObjectId. That's why it cannot populate. Your code is correct.

Sequelize update instance and got "SyntaxError: "undefined" is not valid JSON"

I'm using Sequelize with expressjs for my api, I have a model named "Order" for the orders of the website im currently making, this is my model order:
module.exports = (sequelize, Sequelize) => {
const Order = sequelize.define("order", {
uid: {
type: Sequelize.STRING
},
author: {
type: Sequelize.TEXT('long'),
get: function() {
return JSON.parse(this.getDataValue('author'));
},
set: function(author) {
this.setDataValue('author', JSON.stringify(author));
}
},
cart: {
type: Sequelize.TEXT('long'),
get: function() {
return JSON.parse(this.getDataValue('cart'));
},
set: function(cart) {
this.setDataValue('cart', JSON.stringify(cart));
}
},
delivery: {
type: Sequelize.TEXT('long'),
get: function() {
return JSON.parse(this.getDataValue('delivery'));
},
set: function(delivery) {
this.setDataValue('delivery', JSON.stringify(delivery));
}
},
shipmethod: {
type: Sequelize.STRING
},
paymethod: {
type: Sequelize.STRING
},
totalprice: {
type: Sequelize.DECIMAL
},
cryptoprice: {
type: Sequelize.DECIMAL
},
payed: {
type: Sequelize.DECIMAL
},
promoCode: {
type: Sequelize.STRING
},
status: {
type: Sequelize.STRING
}
});
return Order;
}
All was working good, until I try to update an order, like this:
router.post('/payment/crypto', async (req, res) => {
const {order, currency} = req.body;
if (!order, !currency) return res.status(404).json({error: 'not found'});
console.log(order);
console.log(currency);
try {
const orderDb = await db.orders.findOne({where:{uid: order}});
if (!orderDb) return res.status(404).json({error: 'not found'});
const cryptoPrice = await crypto.convertPrice(currency, (parseFloat(orderDb.totalPrice) + 5));
// HERE
await db.orders.update({cryptoprice: cryptoPrice}, { where: {uid: order}});
const wallet = await crypto.generateWallet(currency, '1P5ZEDWTKTFGxQjZphgWPQUpe554WKDfHQ', 'https://google.fr');
return res.status(200).json({address: wallet.address, price: cryptoPrice});
} catch (error) {
console.error(error);
return res.status(404).json({error: error});
}
});
The findOne method works correctly, but when just after I update this order, I got this error:
SyntaxError: "undefined" is not valid JSON
at JSON.parse (<anonymous>)
at model.get (shopapp\back\src\database\models\Order.model.js:9:29)
at model.get (shopapp\back\node_modules\sequelize\lib\model.js:2116:41)
at model.get (shopapp\back\node_modules\sequelize\lib\model.js:2138:33)
at order.update (shopapp\back\node_modules\sequelize\lib\model.js:1877:44)
at shopapp\back\src\routes.js:132:29
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
The line number 9 of my Order.model.js is :
get: function() {
return JSON.parse(this.getDataValue('author'));
},
I dont understand cause the author column is not null, and even with the findOne I can get it

Can't Understand code execution order Javascript

I am learning mongoose and I'm unable to understand some code execution order of javascript
Code:
const mongoose = require("mongoose");
mongoose.connect("mongodb://localhost:27017/fruitsDB");
const fruitSchema = new mongoose.Schema({
name: {
type: String,
required: [true, "Please check your data entry, no name specified!"],
},
rating: {
type: Number,
min: 1,
max: 10,
},
review: String,
});
const Fruit = mongoose.model("Fruit", fruitSchema);
// Reading data from database
Fruit.find((err, fruits) => {
if (err) {
console.log(err);
} else {
// console.log(fruits);
mongoose.connection.close();
fruits.forEach((fruit) => {
console.log(fruit.name);
});
}
});
// Updating data in database
Fruit.updateOne({ name: "Kiwi" }, { name: "Peach" }, (err) => {
if (err) {
console.log(err);
}
else {
console.log("Successfully updated data");
}
});
// Deleting data in database
Fruit.deleteOne({ name: 'Peach' }, (err) => {
if (err) {
console.log(err);
}
else {
console.log('Data deleted successfully');
}
})
console.log output:
I am unable to understand why the Update function in running before the find() function, can anyone explain this to me please?

Remove document with references Mongoose

I'm having trouble removing Question when Survey gets deleted which is referenced in the Survey model. The survey gets deleted, but the question still remains in the database.
Survey Schema:
let surveyModel = mongoose.Schema(
{
Title: String,
Type: [String],
Questions: { type: mongoose.Schema.Types.ObjectId, ref: "questions" },
Answered: { type: Number, default: 0 }, // how many times users answered
DateCreated: { type: Date, default: Date.now }, // date created
Lifetime: { type: Date, default: Date.now }, // Survey expiry
User: { type: mongoose.Schema.Types.ObjectId, ref: "users" }
},
{
collection: "surveys",
}
);
Question Schema:
let questionModel = mongoose.Schema(
{
MC: {
QuestionText: String,
Options: [String],
},
TF: {
QuestionText: String,
Options: Boolean,
}
},
{
collection: "questions",
}
);
module.exports = mongoose.model("Question", questionModel);
Code I have right now:
// process survey delete
module.exports.processDeletion = (req, res, next) => {
let id = req.params.id;
Survey.remove({ _id: id }, (err) => {
Question.remove({_id: { $in: req.body.Questions }}, (err, res) => {
if (err) {
console.log(err);
res.end(err);
}
});
if (err) {
console.log(err);
res.end(err);
} else {
// refresh survey list
res.redirect("/live-surveys");
}
});
};
Your first step should be delete childrens, that is Question.
Note: i think "Questions" should be more of 1, then it must be an array of Reference in the Survey model. But, for this example it will to be as you have setted.
Then, your delete route, may to be some as:
router.delete("/delete/:surveyById", deleteSurvey");
router.param("surveyById", surveyId"); //This one is your middleware
//surveyController.js
const Survey = require("../models/Survey");
const Question = require("../models/Question");
exports.surveyId = (req, res, next, id) => {
Survey.findById(id).exec((err, data) => {
if(!data || err) return res.status(400).json({error: "Survey not found")};
else {
req.survey = data;
next();
}
)};
};
exports.deleteSurvey = (req, res) => {
Questions.findByIdAndRemove(req.survey.Questions) //Here your Questions Id
.exec((err, data)) => {
if(err) return res.status(400).json({error: "Error to delete questions"});
Survey.findByIdAndRemove(req.survey._id).exec((err, data) => {
if(err) return res.status(400).json({error: "Error to delete Survey"});
return res.json({ message: "Deleted")};
});
});
};
Also you can do with async await if you prefer, is the same, and you will have a better control about your code.

only return _id from mongoose.find

want to fetch all users but just return list of _ids , checked the saved data in db everything seems good.
this is the user model
let UserSchema = new mongoose.Schema({
firstName: {
type: String,
minlength: 3,
trim: true,
},
lastName: {
type: String,
minlength: 3,
trim: true,
},
biography: {
type: String,
minlength: 5,
trim: true,
},
});
UserSchema.methods.toJSON = function () {
let user = this;
let userObject = user.toObject();
return _.pick(userObject, ["_id", "firstName", "email"]);
};
and this is my controller function
const controller = {
fetchUsers :async (_req, res) => {
try {
await User.find({})
.then((users) => {
res.status(200).send(users);
})
.catch((err) => {
res.status(400).send(err);
});
} catch (error) {
res.status(400).json({
Error: `something is wrong. ${error}`,
});
}
}
}
the result is that i tested in postman is :
[
{
"_id": "5fe26ba0d290a216c0fe6d5d"
},
{
"_id": "5fe26c8e40ca9a06b8c96259"
},
]
Don't use .then & await both . Try this once. Assuming model is correct.
const controller = {
fetchUsers :async (_req, res) => {
try {
const users=await User.find({}).exec()
if(users){
res.status(200).send(users);
}
else{
res.status(404).send("no user found");
};
} catch (error) {
res.status(500).json({
Error: `something is wrong. ${error}`,
});
}
}
}
problem is UserSchema.methods.toJSON method there isn't any email field, if we want to filter our output data it's better to filter it by mongoose.find({"condition"},{"fields"})

Categories