What is node package walker? - node.js

I've taken up the job from another freelancer who isn't currently engaged on this project.
He has done some work which I don't understand. Can anyone help me with that.
Every time a user hires a parking spot, I want to notify a merchant.
here is the query to create a booking:
exports.createBooking = async (req, res) => {
try {
const user = await Auth.findOne({ _id: req.data.id });
if (!user) return res.status(404).json({ error: "User not found" });
const bookingDetails = new Booking({
userId: req.data.id,
parkingId: req.body.parkingId,
duration: req.body.duration,
date: moment(req.body.date).format("MMM DD, YYYY"),
startTime: req.body.startTime,
endTime: req.body.endTime,
paymentAmount: req.body.paymentAmount,
isFeePaid: req.body.isFeePaid,
status: "sent",
});
bookingDetails.populate("walkerId");
const save = await bookingDetails.save();
// send notification to walker
let notification_data = {
name: `${owner.basicInfo.fullName}`,
date: moment(req.body.date).format("MMM DD, YYYY"),
startTime: req.body.startTime,
};
let { title, body } = notificationTypes.addBooking(notification_data);
let data = {
senderId: req.data.id,
receiverId: req.body.walkerId,
notificationSendTo: "walker",
title,
body,
};
sendNotification(data);
return res.status(200).json({
success: true,
msg: "Service Booked",
data: { details: save },
});
} catch (error) {
return res.status(500).json({ error: error.message });
}
};
And the booking schema looks like this:
const bookingSchema = new mongoose.Schema(
{
parkingId: {
type: mongoose.Schema.Types.ObjectId,
ref: "Parking",
},
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: "Auth",
},
duration: {
type: String,
},
date: {
type: String,
},
startTime: {
type: Date,
},
endTime: {
type: Date,
},
isFeePaid: {
type: Boolean,
default: false,
},
status: {
type: String,
enum: [
"confirmed",
"sent",
"pending",
"accepted",
"rejected",
"cancelled",
"start",
"completed",
],
},
isBookingCancelled: {
cancelBy: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
},
value: {
type: Boolean,
default: false,
},
cancellationReason: {
type: String,
maxlength: 255,
trim: true,
},
},
paidAmount: {
type: Number,
},
paymentId: {
type: mongoose.Schema.Types.ObjectId,
ref: "Payment",
},
paymentAmount: {
type: Number,
},
isStarted: {
type: Boolean,
default: false,
},
isEnabled: {
type: Boolean,
default: false,
},
},
{
timestamps: true,
}
);
I am aware that the schema lacks a walkerId, which would cause an error to be thrown, but I have never used walker thus I have no idea how to incorporate it.

Related

MongoDB geting an empty array from an aggregation

So I created this controller to get me the sum of all the orders totalPrice made by months
const getMonthlyOrderTotal = async (req, res) => {
try {
const year = req.params.year;
const aggregatePipeline = [
{
$match: {
createdAt: {
$gte: new Date(`${year}-01-01T00:00:00.000`),
$lt: new Date(`${year}-12-31T23:59:59.999`)
}
}
},
{
$group: {
_id: {
$month: "$createdAt"
},
total: {
$sum: "$totalPrice"
}
}
},
{
$sort: {
_id: 1
}
}
];
const orderTotals = await Order.aggregate(aggregatePipeline);
res.json(orderTotals);
} catch (err) {
res.status(500).json({ message: err.message });
}
};
this is the orderModel I am using
import mongoose from "mongoose";
const orderSchema = mongoose.Schema(
{
user: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: "User",
},
client: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: "Client",
},
orderItems: [
{
name: { type: String, required: true },
qty: { type: Number, required: true },
image: { type: String },
price: { type: Number, required: true },
product: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: "Product",
},
},
],
totalPrice: {
type: Number,
required: true,
default: 0.0,
},
taxPrice: {
type: Number,
required: true,
default: 0.0,
},
isPaid: {
type: Boolean,
required: true,
default: false,
},
paidAt: {
type: Date,
},
isDelivered: {
type: Boolean,
required: true,
default: false,
},
deliveredAt: {
type: Date,
},
},
{
timestamps: true,
}
);
const Order = mongoose.model("Order", orderSchema);
export default Order;
and when I try to test this API in postman "http://localhost:5001/orders/orderstotal/2022" I always get an empty array even though there is stored data in mongoDB orders Collection

Mongoose Schema type Object Id Mapping

Backend Code:
This is orderModel.js
import mongoose from "mongoose";
const orderSchema = mongoose.Schema(
{
user: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: "User",
},
orderItems: [
{
name: { type: String, required: true },
qty: { type: String, required: true },
image: { type: String, required: true },
price: { type: String, required: true },
productId: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: "Product",
},
},
],
deliveryAddress: {
address: { type: String, required: true },
area: { type: String, required: true },
// gender: { type: String, required: true },
postalCode: { type: String, required: true },
district: { type: String, required: true },
division: { type: String, required: true },
country: { type: String, required: true, default: "Bangladesh" },
},
paymentMethod: {
type: String,
required: true,
},
paymentStatus: {
id: { type: String },
status: { type: String },
update_time: { type: String },
email: { type: String },
},
taxPrice: {
type: Number,
required: true,
default: 0.0,
},
deliveryCost: {
type: Number,
required: true,
default: 0.0,
},
totalPrice: {
type: Number,
required: true,
default: 0.0,
},
discount: {
type: Number,
required: true,
default: 0.0,
},
isPaid: {
type: Boolean,
required: true,
default: false,
},
paidAt: {
type: Date,
},
isDelivered: {
type: Boolean,
required: true,
default: false,
},
deliveredAt: {
type: Date,
},
},
{
timeStamps: true,
}
);
const Order = mongoose.model("Order", orderSchema);
export default Order;
This is orderController.js -
import asyncHandler from "express-async-handler";
import Order from "../models/orderModel.js";
// review: desc => Create New Order
// review: route => POST api/orders
// review: access => Private
const createOrder = asyncHandler(async (req, res) => {
const {
orderItems,
deliveryAddress,
paymentMethod,
taxPrice,
deliveryCost,
discount,
totalPrice,
} = req.body;
if (orderItems && orderItems.length === 0) {
res.status(400);
throw new Error("No order items");
} else {
try {
const order = new Order({
orderItems,
user: req.user._id,
deliveryAddress,
paymentMethod,
taxPrice,
deliveryCost,
discount,
totalPrice,
});
console.log("ORDER CREATED", order);
const createdOrder = await order.save();
console.log("ORDER saved", createdOrder);
res.status(201).json(createdOrder);
} catch (error) {
res.status(400);
throw new Error("Invalid order data", error);
}
}
});
// review: desc => GET order by id
// review: route => GET api/orders/:id
// review: access => private
const getOrderById = asyncHandler(async (req, res, next) => {
const order = await Order.findById(req.params.id).populate(
"user",
"name email"
);
if (order) {
res.json(order);
} else {
res.status(404);
throw new Error("Order not found");
}
});
export { createOrder, getOrderById };
Frontend Code:
const handleSubmit = (e) => {
e.preventDefault();
dispatch(
createOrder({
orderItems: cartItems,
deliveryAddress: addressObject,
paymentMethod,
taxPrice: vat,
deliveryCost,
discount,
totalPrice,
})
);
};
Here When I am sending request to backend, It's giving me validation error. As - orderItems.0.productId: Path productId is required. Why I am getting this error ? mongoose should not map data and get productId from sent cartItems, where is a field is _id ? Your time and help is most appreciated, Thanks.

Want to use mongoose updateOne but it is not updating

I want to update the type: reported to type: pending under the reportStatus, but when I try it on postman I keep on getting
n:1 ,n:modified:1 and ok:1
report: [
{
category: {
type: mongoose.Schema.Types.ObjectId,
ref: "CrimeCategory",
required: true,
},
location: {
type: mongoose.Schema.Types.ObjectId,
ref: "Location",
required: true,
},
reportText: {
type: String,
required: true,
},
reportStatus: {
type: mongoose.Schema.Types.Mixed,
default: function () {
return [
{ type: "reported", date: new Date(), isCompleted: true },
{ type: "pending", isCompleted: false },
{ type: "investigating", isCompleted: false },
{ type: "solved", isCompleted: false },
];
},
},
},
],
This is the controller where I am trying to update the types that is in the model, what am I doing wrong?
const crimeReport = require("../../model/crimereport");
exports.updateReport = (req, res) => {
crimeReport
.updateOne(
{ _id: req.body.reportId, "report.reportStatus": req.body.type },
{
$set: {
"report.reportStatus.$": [
{
type: req.body.type,
date: new Date(),
isCompleted: true,
},
],
},
}
)
.exec((error, report) => {
if (error) return res.status(400).json({ error });
if (report) {
res.status(200).json({ report });
}
});
};
The postman post request:
{
"reportId": "607b2b25876fa73ec4437440",
"type":"pending"
}
This is the post result from postman:
{
"report": {
"n": 0,
"nModified": 0,
"ok": 1
}
}
It seems like, you are sending reportId in the body of post request as a string while the Mongodb document's id is of type ObjectId. You need to typecast the reportId into ObjectId, before querying to Mongodb. Since you are using Mongoose, this is the way it should be done:
mongoose.Types.ObjectId(req.body.reportId)

Mongoose - Cast to ObjectId failed for value "[object Object]" at path _id

I have the below schema:
var StorySchema = new Schema({
title: { type: String, required: true },
users: {
id: { type: Schema.ObjectId, ref: 'users' },
creator: { type: Boolean }
},
maxlines: { type: Number, default: '10'},
lines: {
text: { type: String },
entered_at: { type: Date },
user: {
id: { type: Schema.ObjectId, ref: 'users' }
}
},
created_date: { type: Date, default: Date.now },
updated_date: { type: Date, default: Date.now },
})
I've got the below which does the query:
exports.view = function (req, res) {
Stories
.findOne({
_id: req.params.id
})
/*.populate('users') */ **<-- If I uncomment this I get the error**
.exec(function (err, story) {
if (err) {
res.json(200, {
success: "false",
message: err.message
})
} else if (story) {
res.json({
sucess: "true",
message: story
})
} else {
res.json(200, {
sucess: "false",
message: "story not found"
})
}
})
}
As above if I add .populate('users') it flags the below error:
{
"success": "false",
"message": "Cast to ObjectId failed for value \"[object Object]\" at path \"_id\""
}
I'm calling /view/51fc2e02576f2dc058000001 (which is an Object ID of the stories table), without the .populate('users') if I call the URL it brings back the document.
The users -> id value is populated with ObjectId("51fbe87ec137760025000001") - which is a valid _id in the users collection
I cannot see what I'm missing?
Added User Schema
var UserSchema = new Schema({
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
username: { type: String, required: true, unique: true },
provider: { type: String, required: true, enum: ['local', 'facebook'] },
password: { type: String, required: true },
avatar: { type: String, default: 'http://i.imgur.com/1PtcFos.jpg' },
gender: { type: String, required: true, uppercase: true, enum: ['M', 'F'] },
facebook: {
id: { type: String },
token: { type: String },
token_expiry: { type: Date }
},
device: {
token: { type: String },
type: { type: String, enum: ['ios', 'android'] },
badge: { type: Number },
id: { type: String },
created_date: { type: Date, default: Date.now },
updated_date: { type: Date, default: Date.now }
},
created_date: { type: Date, default: Date.now },
updated_date: { type: Date, default: Date.now }
})
I think you can only do .populate('users.id'). Populate is to use the reference Object to replace the id field. Please take a look at the doc.

mongoose save embedded document

I have the following schema:
var StorySchema = new Schema({
title: { type: String, required: true },
users: {
id: { type: Schema.ObjectId, ref: 'Users' },
creator: { type: Boolean }
},
maxlines: { type: Number, default: '10'},
lines: {
text: { type: String },
entered_at: { type: Date },
user: {
id: { type: Schema.ObjectId, ref: 'Users' }
}
},
created_date: { type: Date, default: Date.now },
updated_date: { type: Date, default: Date.now },
})
I want to push data into lines and am trying to do so with the below update:
exports.update = function (req, res) {
Stories
.findOne({ _id: req.params.id }, function (err, story) {
if (err) {
res.json(200, {
success: "false",
message: err.message
})
} else {
story.maxlines = story.maxlines - 1
story.lines.push ({
text : req.body.text,
'user.id' : req.headers.id,
entered_at : new Date().toISOString()
})
story.save(function(err, story) {
if (err) {
res.json(200, {
success: "false",
message: err.message
})
} else if (story) {
res.json({
sucess: "true",
message: story
})
}
})
}
})
}
I get an error of TypeError: Object { user: {} } has no method 'push', not entirely sure how to update the lines and the user associated with the line
Because story.lines is not an Array. You probably need to update the Schema to convert the lines to type Array in this way:
var LineSchema = new Schema({
text: {
type: String
},
entered_at: {
type: Date
},
user: {
id: {
type: Schema.ObjectId,
ref: 'Users'
}
}
});
var StorySchema = new Schema({
title: {
type: String,
required: true
},
users: {
id: {
type: Schema.ObjectId,
ref: 'Users'
},
creator: {
type: Boolean
}
},
maxlines: {
type: Number,
default: '10'
},
lines: [LineSchema],
created_date: {
type: Date,
default: Date.now
},
updated_date: {
type: Date,
default: Date.now
},
})

Resources