Related
I'm having an error on my database where the sub array that I push to my database is missing and created a new id which means it detects data pushed inside.
here's the data I pushed. (toDeliver array has 4 objects inside).
I'm trying to send the whole array along with the string outside of the array.
after the request here what I receive on my database which is mongoDB.
the object inside toDeliver array is incomplete and created a ObjectId.
but the string outside of array was save the database.
here's my schema.
const OwnerSchema = mongoose.Schema({
username: {
require: true,
type: String,
},
password: {
require: true,
type: String,
},
isAdmin: {
type: Boolean,
default: true,
},
store: [
{
product_identifier: {
type: String,
require: true,
},
productname: {
type: String,
required: true,
},
price: {
type: Number,
required: true,
},
quantity: {
type: Number,
required: true,
},
categoryfilter: {
type: String,
required: true
},
description: {
type: String,
required: true,
},
specs: {
type: String,
required: true
},
imageBase64: {
type: String,
required: true,
},
timestamp: {
type: String,
required: true,
}
}
],
delivery: [
{
clientname: {
type: String,
required: true
},
address: {
type: String,
required: true
},
email: {
type: String,
required: true
},
number: {
type: Number,
required: true
},
toDeliver: [
{
product_identifier: {
type: String,
require: true,
},
productname: {
type: String,
required: true
},
price: {
type: Number,
required: true
},
}
],
toDeliverPaidViaPaypal: [
{
product_identifier: {
type: String,
require: true,
},
productname: {
type: String,
required: true
},
price: {
type: Number,
required: true
},
}
]
}
]
});
here's my backend.
export const delivery = async (req,res) => {
const { id } = req.params;
console.log(id);
console.log(req.body);
try {
if(!id) return res.status(404).json({ message: 'ID not found' });
await OwnerModels.findByIdAndUpdate(id,
{
$push: {
delivery:
{
clientname: req.body.delivery[0].clientname,
address: req.body.delivery[0].address,
email: req.body.delivery[0].email,
number: req.body.delivery[0].number,
toDeliver:
[{
product_identifier: req.body.delivery[0].toDeliver.product_identifier,
productname: req.body.delivery[0].toDeliver.productname,
price: req.body.delivery[0].toDeliver.price
}]
,
toDeliverPaidViaPaypal: []
}
}
},
{
new: true,
},(err,res)=> {
if(err) return console.log({ error: err });
console.log({ result: res.delivery });
}).clone();
} catch (error) {
res.status(500).json({ message: 'Server error' });
}
}
hope ya guys can help me. thank you
I think you need to add square brackets around the toDeliver object to make it an array like your console object:
$push: {
delivery: {
clientname: req.body.delivery[0].clientname,
address: req.body.delivery[0].address,
email: req.body.delivery[0].email,
number: req.body.delivery[0].number,
toDeliver: [{
product_identifier: req.body.delivery[0].toDeliver.product_identifier,
productname: req.body.delivery[0].toDeliver.productname,
price: req.body.delivery[0].toDeliver.price
}],
toDeliverPaidViaPaypal: []
}
}
Also add "_id: false" to toDelivery in your schema to repress id from being generated for the sub-object:
toDeliver: [
{
product_identifier: {
type: String,
require: true,
},
productname: {
type: String,
required: true
},
price: {
type: Number,
required: true
},
_id: false,
}
],
I am trying to build edit function in my web app using Mongoose and expressJS as backend, I want to update a single field in lessonLog which is an array of lessonLog with individual objectId, I tried it with the following code but not working as I intended, please advise. thank you in advance!
{
Object _id : 601e7877cc4bc5047860831b ObjectId,
date : 2021-02-05T16:00:00.000+00:00 Date,
tempoMin : 71,
tempoMax : 206,
title : Khulau,
intonation : test,
phrasing : test,
articulation : technique : test,
notes : test ,
}
const studentsSchema = new mongoose.Schema({
name: { type: String, require: true },
email: { type: String, require: true },
contact: { type: String, require: true },
activities: {
exam: { type: String, require: true },
recording: { type: String, require: true },
theory: { type: String, require: true },
competition: { type: String, require: true },
orchestra: { type: String, require: true },
},
teacher: { type: mongoose.Types.ObjectId, require: true, ref: "teachers" },
repertoire: [{ type: String, require: true }],
**lessonLog: [
{
date: { type: Date, require: true },
tempoMin: { type: String, require: true },
tempoMax: { type: String, require: true },
title: { type: String, require: true },
scales: { type: String, require: true },
intonation: { type: String, require: true },
phrasing: { type: String, require: true },
articulation: { type: String, require: true },
technique: { type: String, require: true },
notes: { type: String, require: true },
},**
],
});
here is the query:
const editLessonLog = async (req, res, next) => {
try {
await Students.findOneAndUpdate(
{
lessonLog: { _id: req.body.lessonLogId },
},
{
$set: {
lessonLog: {
date: req.body.lessonDate,
tempoMin: req.body.tempo[0],
tempoMax: req.body.tempo[1],
title: req.body.title,
intonation: req.body.intonation,
phrasing: req.body.phrasing,
articulation: req.body.articulation,
technique: req.body.technique,
notes: req.body.notes,
},
},
}
);
// console.log(student);
} catch (err) {
const error = new HttpError(
"Cannot delete lesson log, please try again.",
500
);
return next(error);
}
you should using $ based on documentation
The positional $ operator identifies an element in an array to update without explicitly specifying the position of the element in the array
so just try
const editLessonLog = async (req, res, next) => {
try {
await Students.findOneAndUpdate(
{
"lessonLog._id": req.body.lessonLogId
},
{
$set: {
"lessonLog.$": {
date: req.body.lessonDate,
tempoMin: req.body.tempo[0],
tempoMax: req.body.tempo[1],
title: req.body.title,
intonation: req.body.intonation,
phrasing: req.body.phrasing,
articulation: req.body.articulation,
technique: req.body.technique,
notes: req.body.notes,
},
},
}
);
// console.log(student);
} catch (err) {
const error = new HttpError(
"Cannot delete lesson log, please try again.",
500
);
return next(error);
}
I am using molecularjs actions to enter data into my database. Primarily I am using NodeJS with mongoose to define models. So far I am able to create a model but when I try to create an one-to-many relation it gives me this error
errors: { 'deliveryParcels.0': CastError: Cast to [ObjectId] failed
for value "[{"parcelId":"LHE660851871415","address":"24 E muhafiz town
lahore","type":"COD","addressLocation":{"lat":31.4532941,"lng":74.2166403},"customerName":"ALI
MALHI","customerPhone":"3314488396","processingStatus":"pending","amount":2500,"vendorOrderId":"other"}]"
at path "deliveryParcels.0"
I want both collections rider-tasks and delivery-parcels to be created simultaneously but only the rider-tasks collection gets created but not the delivery-parcels. What am I doing wrong in my schema?
Here are my models
rider-tasks model
import mongoose, { Schema } from "mongoose";
import { getDbConnection } from "../../../utils/db/db-connect";
/* eslint-disable id-blacklist */
import { IRiderTaskModel } from "../interfaces/rider-task.interface";
const RiderTaskSchema: Schema<IRiderTaskModel> = new Schema<IRiderTaskModel>(
{
_id: { type: String, required: true, unique: true },
riderId: { type: String, required: true },
totalAmount: { type: Number, required: true },
riderName: { type: String, required: true },
cityId: { type: String, required: true },
cityName: { type: String, required: true },
status: { type: String, required: true },
adminName: { type: String, required: true },
adminId: { type: String, required: true },
createdAt: { type: Date, required: true },
deliveryParcels: [
{
type: Schema.Types.ObjectId,
ref: "delivery-parcels",
},
],
},
{ _id: true }
);
const RiderTask = getDbConnection("deliveryManagement").model<IRiderTaskModel>(
"rider-tasks",
RiderTaskSchema
);
export { RiderTask };
delivery-parcels
import mongoose, { Schema } from "mongoose";
import { getDbConnection } from "../../../utils/db/db-connect";
import { IDeliveryParcelModel } from "../interfaces/delivery-parcels.interface";
const DeliveryParcelsSchema: Schema<IDeliveryParcelModel> = new Schema<IDeliveryParcelModel>(
{
parcelId: { type: String, required: true },
address: { type: String, required: true },
addressLocation: {
lat: { type: Number, required: true },
lng: { type: Number, required: true },
},
customerName: { type: String, required: true },
customerPhone: { type: String, required: true },
processingStatus: { type: String, required: true },
amount: { type: Number, required: true },
riderTaskId: { type: Schema.Types.String, ref: "rider-tasks" },
type: { type: String, required: true, enum: ["COD", "NONCOD"] },
postedStatus: {
status: { type: String },
statusKey: { type: String },
signature: { type: String },
reason: { type: String },
checkBoxData: [{ type: String }],
adminId: { type: String },
adminName: { type: String },
},
}
);
const DeliveryParcels = getDbConnection(
"deliveryManagement"
).model<IDeliveryParcelModel>("delivery-parcels", DeliveryParcelsSchema);
export { DeliveryParcels };
My service
private async createdRiderTaskHandler(ctx: Context<IRiderTaskModel>) {
const { params } = ctx;
const finalData: IParcelData[][] = await Promise.all(
params.deliveryParcels.map((parcel) =>
this.broker.call("parcel-data.getParcels", {
id: parcel.parcelId,
})
)
);
const wrongParcels: string | any[] = [];
const check = finalData[0].filter(
(data) => data.currentStatus.status === "Dispatched"
)[0];
if (check) {
wrongParcels.push(check.parcelId);
const parcel = wrongParcels.join("\r\n");
throw new Error(
'These parcels "' + parcel + '" have already been dispatched'
);
}
const codAmount = params.deliveryParcels
.filter((data, i) => data.type === "COD")
.reduce((total, b) => total + b.amount, 0);
const customId = "RTD-" + Math.floor(100000 + Math.random() * 900000);
try {
const taskData = omit({
...params,
_id: customId,
totalAmount: codAmount,
forceAssignment: false,
createdAt: new Date(),
});
const data = await RiderTask.create(taskData);
return { message: data };
} catch (error) {
this.logger.error(error);
return error;
}
}
In my NodeJS API and MongoDB, I'm trying to delete a record which is a reference to another collection.
What I would like to do is to delete the referred objectId and the records related to the other collection which is referred.
I have 2 models Profiles and Posts and I want to delete the same one post from Profile and Post collection.
I was able to delete the reference id in Profile but I don't know how to delete also the record from Posts collection.
I tried this:
async delete(req, res) {
try {
// Match with username and pull to remove
await Profile.findOneAndUpdate(
{ _id: res.id._id },
{ $pull: { posts: req.params.postId } },
err => {
if (err) {
throw new ErrorHandlers.ErrorHandler(500, err);
}
res.json({ Message: "Deleted" });
}
);
} catch (error) {
res.status(500).send(error);
}
}
And my 2 models:
// Here defining profile model
// Embedded we have the Experience as []
const { Connect } = require("../db");
const { isEmail } = require("validator");
const postSchema = {
type: Connect.Schema.Types.ObjectId,
ref: "Post"
};
const experienceSchema = {
role: {
type: String,
required: true
},
company: {
type: String,
required: true
},
startDate: {
type: Date,
required: true
},
endDate: {
type: Date,
required: false
},
description: {
type: String,
required: false
},
area: {
type: String,
required: true
},
createdAt: {
type: Date,
default: Date.now,
required: false
},
updatedAt: {
type: Date,
default: Date.now,
required: false
},
username: {
type: String,
required: false
},
image: {
type: String,
required: false,
default: "https://via.placeholder.com/150"
}
};
const profileSchema = {
firstname: {
type: String,
required: true
},
surname: {
type: String,
required: true
},
email: {
type: String,
trim: true,
lowercase: true,
unique: true,
required: [true, "Email is required"],
validate: {
validator: string => isEmail(string),
message: "Provided email is invalid"
}
},
bio: {
type: String,
required: true
},
title: {
type: String,
required: true
},
area: {
type: String,
required: true
},
imageUrl: {
type: String,
required: false,
default: "https://via.placeholder.com/150"
},
username: {
type: String,
required: true,
unique: true
},
experience: [experienceSchema],
posts: [postSchema],
createdAt: {
type: Date,
default: Date.now,
required: false
},
updatedAt: {
type: Date,
default: Date.now,
required: false
}
};
const collectionName = "profile";
const profileSchemaModel = Connect.Schema(profileSchema);
const Profile = Connect.model(collectionName, profileSchemaModel);
module.exports = Profile;
const { Connect } = require("../db");
const reactionSchema = {
likedBy: {
type: String,
unique: true,
sparse: true
}
};
const postSchema = {
text: {
type: String,
required: true,
unique: true,
sparse: false
},
profile: {
type: Connect.Schema.Types.ObjectId,
ref: "Profile",
},
image: {
type: String,
default: "https://via.placeholder.com/150",
required: false
},
createdAt: {
type: Date,
default: Date.now,
required: false
},
updatedAt: {
type: Date,
default: Date.now,
required: false
},
reactions: [reactionSchema],
comments: {
type: Connect.Schema.Types.ObjectId,
ref: "Comment",
required: false
}
};
const collectionName = "post";
const postSchemaModel = Connect.Schema(postSchema);
const Post = Connect.model(collectionName, postSchemaModel);
module.exports = Post;
Just add a query to remove the post after pulling it's ID from the profile collection:
async delete(req, res) {
try {
// Match with username and pull to remove
await Profile.findOneAndUpdate(
{ _id: res.id._id },
{ $pull: { posts: req.params.postId } },
// You don't need an error callback here since you are
// using async/await. Handle the error in the catch block.
);
await Posts.remove({ _id: req.params.postId });
} catch (error) {
// This is where you handle the error
res.status(500).send(error);
}
}
I have this data structure. I would like to push a new sibling into a specific members sibling array:
const FamilySchema = mongoose.Schema({
username: { type: String, required: true },
family_name: { type: String, required: true },
password: { type: String, required: true },
members: [
{
fname: { type: String, required: true },
lname: { type: String, required: true },
mname: { type: String },
birth_date: { type: String },
birth_town: { type: String },
birth_state: { type: String },
death_date: { type: String },
death_town: { type: String },
death_state: { type: String },
short_bio: { type: String },
long_bio: {type: String },
parents: [
{
parent_id: { type: String, required: true }
}
],
siblings: [
{
sibling_id: { type: String, required: true }
}
],
children: [
{
children_id: { type: String, required: true }
}
],
pictures: [
{
url: { type: String, required: true }
}
],
}
]
});
I want to push a new sibling into the sibling array for a SPECIFIC member in the larger family document. I'm trying to do it like this, and it's not working.
Family
.update(
{
_id: FAMILY_ID,
"members._id" : MEMBER_ID
},
{
$push : {
"members.$.siblings" : {
"sibling_id": THE_VALUE_I_WANT_ADDED
}
}
}
);
Any thoughts? My Mongoose knowledge is failing me.