mongoose expressJS update single field in nested array - node.js

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);
}

Related

How to update an array inside mongoose object with respect to the object ids

I need to update a property (seen : false) to seen : true
below is my schema
const ChatSchema = mongoose.Schema({
chatId: { type: String, required: true, unique: true },
messages: [
{
message: { type: String, required: true },
sendBy: { type: String, required: true },
sendTo: { type: String, required: true },
seen: { type: Boolean, default: false },
date: { type: Date, default: Date.now()}
},
],
})
im getting the message ids of those to mark to true like
console.log(data.messageIds);
[ '62de69459ed612f9122b4e5d', '62de69549ed612f9122b4e66' ],
and i tried the following way, but its not working as expected
const query={chatId:chatId};
const update = {$set: {"messages.$[e].seen": true } };
const options={
arrayFilters: [{ "e._id": data.messageIds}],
new: true
};
Chat.findOneAndUpdate(query, update,options, function (error, result) {
if (error) {
console.log("error: " + error.message);
return;
}
}).clone();

Mongoose $push whole array in database

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,
}
],

What is the correct way to enter an Array?

I want to enter data via Postman into an array form using id Collection in the database also how can I write a valid JSON script for the modal for the modal
Add data using id Collection
controller
const addAcademicExperience = async (req, res, next) => {
//const id = req.params.id;
const {AcademicExperience} = req.body;
let academicexperience;
try {
academicexperience = await AcademicExperience.findByIdAndadd(id, {
AcademicExperience
});
await academicexperience.save();
} catch (err) {
console.log(err);
}
if (!academicexperience) {
return res.status(404).json({ message: 'Unable to Add' })
}
return res.status(200).json({academicexperience});
model Schema
Some data is required in an array and some are not
per user per user
To clarify, the site is similar to LinkedIn
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const FacultySchema = new Schema({
Faculty_ID: {
type: Number,
required: true,
unique: true,
},
Name: {
type: String,
required: true,
},
Phone_Number: {
type: String,
required: true,
},
Email: {
type: String,
required: true,
},
AcademicExperience: [{
institution: { type: String, required: true },
rank: { type: String, required: true },
title: { type: String, required: true },
working: { type: Boolean, required: true },
}
],
Certifications:
{
type: String,
require: true,
},
Currentm_embership:
{
type: String,
require: true,
},
Servicea_ctivites:
{
type: String,
require: true,
},
Professional:
{
type: String,
require: true,
},
Education:[ {
degree: { type: String, required: true },
discpilne: { type: String, required: true },
institution: { type: String, required: true },
year: { type: Date, required: true },
}
],
Non_academic_experines:[
{
Company: { type: String, required: true },
title: { type: String, required: true },
working: { type: Boolean, required: true },
Description_of_position: { type: String, required: true },
}
],
Honoers_and_awards:
{
type: String,
require: true,
},
Puplications_and_presentation:
{
type: String,
require: true,
},
});
module.exports = mongoose.model("Faculty", FacultySchema);

Pushing an element in an array of array

This is my schema...How can I push an element in an array of an array?
example: I've to insert an element in (patient.problems.feedback) in an already existing document. please help me how to code in node js-MongoDB
let Patient = new Schema({
patient: {
patientId: {
type: String,
required: false
},
name: {
type: String,
required: true
},
age: {
type: String,
required: true
},
gender: {
type: String,
required: true
},
city: {
type: String
},
phoneNumber: {
type: String,
min: 10,
max: 10
},
referredBy: {
type: String
},
createdAt: {
type: String
}
},
Problems: [{
problemId: {
type: String,
required: false
},
problem: {
type: String,
required: true
},
howLongSuffered: {
type: String
},
medicinesFollowed: {
type: String
},
createdAt: {
type: String
},
feedbacks: [{
feedbackId: {
type: String,
required: false
},
feedback: {
type: String,
required: false
},
updatedAt: {
type: String
}
}]
}]
})
**This is my controller
How can I update the existing document by pushing an element into the feedbacks
**
exports.addFeedbackDetailsForExistingProblem = async function(req, res) {
try {
let feedbackCreatedDate = new Date();
feedbackCreatedDate = feedbackCreatedDate.toDateString();
await patientModel.findById(req.params.id).then(async(result) => {
console.log(result + req.body.id);
await result.updateOne({ 'Problems._id': req.body.id }, {
$push: {
'Problems.feedbacks': {
'feedbacks.feedback': req.body.feedback,
'feedbacks.createdAt': feedbackCreatedDate
}
}
})
});
} catch (err) {
res.status(500).send("Something Went Wrong");
}
}

Nodejs:Array data not added in mongodb

This is my model profile.js
var mongoose = require('mongoose');
const ProfileSchema = mongoose.Schema({
educationinfo: [{
universityname:
{
type: String,
required: true
},
degree:
{
type: String,
required: true
},
coursecompletionyear:
{
type: String,
required: true
},
collegename:
{
type: String,
required: true
},
specialization:
{
type: String,
required: true
},
marks:
{
type: String,
required: true
},
courselevel:
{
type: String,
required: true
}
}]
});
const Profile = module.exports = mongoose.model('Profile', ProfileSchema);
This is my route.js post function
router.post('/addprofiledetails', function(req, res, next) {
let newProfile = new Profile({
$educationinfo:[{
universityname:req.body.universityname,
degree:req.body.degree
}]
});
newProfile.save((err, profile) => {
if (err) {
res.json({ msg: 'Failded to add profiledetails' });
} else {
res.json({ msg: 'successfully add profile details' });
}
});
});
I got success msg in post function but the data not added in mongodb. i don't know where i did mistake .please help me.
In mongoDB I got data like,
{
"educationinfo": [],
"_id": "5bed14b93a107411a0334530",
"__v": 0
}
I want details inside educationinfo, please help.
You need to change schema definition and query.
1.remove required from schema Or apply required to those field that you must provide value.
educationinfo: [{
universityname:
{
type: String,
// required: true
},
degree:
{
type: String,
//required: true
},
coursecompletionyear:
{
type: String,
// required: true
},
collegename:
{
type: String,
// required: true
},
specialization:
{
type: String,
//required: true
},
marks:
{
type: String,
// required: true
},
courselevel:
{
type: String,
// required: true
}
}]
2.change $educationinfo with educationinfo
educationinfo:[{
universityname:req.body.universityname,
degree:req.body.degree
}]
Since you marked the properties of educationinfo as required, you need to provide them when you create an instance of Profile. If you don't want to do that you need to remove the required property from those properties that you won't be supplying on instance creation like below:
const mongoose = require('mongoose');
const ProfileSchema = mongoose.Schema({
educationinfo: [{
universityname:
{
type: String,
required: true
},
degree:
{
type: String,
required: true
},
coursecompletionyear:
{
type: String
},
collegename:
{
type: String
},
specialization:
{
type: String
},
marks:
{
type: String
},
courselevel:
{
type: String
}
}]
});
const Profile = module.exports = mongoose.model('Profile', ProfileSchema);
After making those changes, you need to make one more change in your POST route, change $educationinfo to educationinfo
router.post('/addprofiledetails', function(req, res, next) {
const newProfile = new Profile({
educationinfo:[{
universityname: req.body.universityname,
degree: req.body.degree
}]
});
newProfile.save((err, profile) => {
if (err) {
res.json({ msg: 'Failded to add profiledetails' });
} else {
res.json({ msg: 'successfully add profile details' });
}
});
});
The data you insert is incomplete.
The properties in your schema marked as required: true need to be inserted aswell. Because you do not meet the schema requirements, it is failing.

Resources