Mongoose $push whole array in database - node.js

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

Related

Find one and Update mongoose in Node js

I have following code for a chat application based on socket io.
const query={ chatID: chatId }
const update= {
$push: {
messages:{
message: message,
sendBy: sendById,
sendTo: sendTo
}
}
}
const options={upsert: true, new:true}
Chat.findOneAndUpdate(query, update, options, function(error, result) {
if (error){
console.log("error: "+error.message);
return;
}
io.emit("message", result.messages)
}).clone();
now if the chat id doesn't exists it creates new with query and update. But i want it like,
if the query doesnt exist, i have some more params to add to the document. How can i achieve that.
if i add the whole params in query , it wont find the document.
the foloowing is my schema
const ChatSchema = mongoose.Schema({
chatID: { type: String, required: true, unique: true },
participants: [
{ senderId: { type: mongoose.Types.ObjectId, unique: true, required: true } },
{ receiverId: { type: mongoose.Types.ObjectId, unique: true, required: 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() }
},
],
})

How to use values of map function in other functions?

I want to use data returned by a map method into another function.
Here is the route schema:
const routeSchema = new mongoose.Schema(
{
Location: {
from: {
type: mongoose.Schema.Types.ObjectId,
ref: "Location",
required: true,
},
to: {
type: mongoose.Schema.Types.ObjectId,
ref: "Location",
required: true,
},
},
busId: {
type: mongoose.Schema.Types.ObjectId,
ref: "Bus",
required: true,
},
date: {
type: String,
required: true,
},
departureTime: {
type: Number,
required: true,
},
arrivalTime: {
type: Number,
required: true,
},
},
{
timestamps: true,
}
);
and here is the booking schema and in booking table routeId is embedded:
const bookingSchema = new mongoose.Schema({
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
required: true,
},
routeId: {
type: mongoose.Schema.Types.ObjectId,
ref: "Route",
required: true,
},
passengers: [
{
name: { type: String, required: true, trim: true },
gender: { type: String, required: true, trim: true },
age: { type: Number, required: true, trim: true },
}],
phone: {
type: Number,
required: true,
},
email: {
type: String,
required: true,
},
bookingDate: {
type: String,
required: true,
},
fare: {
type: Number,
required: true,
},
seats: {
type: [Number],
required: true,
},
departureDetails: [
{
city: { type: String, required: true, trim: true },
location: { type: String, required: true, trim: true },
time: { type: String, required: true, trim: true },
date: { type: String, required: true, trim: true },
},
],
arrivalDetails: [
{
city: { type: String, required: true, trim: true },
location: { type: String, required: true, trim: true },
time: { type: String, required: true, trim: true },
date: { type: String, required: true, trim: true },
},
],
},{
timestamps:true
});
Here is the map function method:
router.get("/trip/single", async (req, res) => {
if (!req.query.from || !req.query.to || !req.query.date) {
return res.send({
error: "Please enter the data to get the trip",
});
}
const { from, to, date } = req.query;
const routes = await Route.find({
"Location.from": from,
"Location.to": to,
"date": date.toString(),
});
const matchedBus = await routes.filter(() =>{
return Route.busId === routes._id
});
const bookings = await Booking.find({
routeId: { $in: matchedBus.map((matchedBus) => matchedBus._id) },
});
console.log(bookings);
const busIdWithSeatsObj = {};
var busData = matchedBus.map(data => data)
console.log(busData);
This busData console is returning this data:
[
{
Location: {
from: new ObjectId("6295f0986f9e32990d8b3488"),
to: new ObjectId("6295f0c06f9e32990d8b348b")
},
_id: new ObjectId("6295f12c6f9e32990d8b348e"),
busId: new ObjectId("6295f0836f9e32990d8b3485"),
date: '2022-06-02',
departureTime: 11,
arrivalTime: 6.3,
createdAt: 2022-05-31T10:42:52.785Z,
updatedAt: 2022-05-31T10:42:52.785Z,
__v: 0
}
]
Now I want to use only busId and date only in the function below:
for (let i = 0; i < matchedBus.length; i++) {
let currentBusSeats = [];
const busBookings = bookings.filter((booking) => {
return (
//Want to use date and busId data in here
//someData === date.toString() &&
//someData === matchedBus[i]._id
);
});
console.log(busBookings);
busBookings.forEach(() => {
currentBusSeats = [...currentBusSeats, ...Booking.seats];
});
busIdWithSeatsObj[matchedBus[i]._id] = currentBusSeats;
}
res.status(200).send({ routes, matchedBus, busIdWithSeatsObj });
});
How can I do that to get the result?
var busData = matchedBus.map(data => data
'use your for loop inside data and you can get you _id value by data._id'
)

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

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.

Resources