It's along explanation so to make it easier I'll call users x and y.
I got this code, which the intention is to the X (making the requests) add his ID into Y's pending requests as well as his own sent requests.
const postSendBBRequest = async (req, res) => {
const userRecipient = await User.findById(req.params.id)
const userSender = await User.findById(req.userId);
const senderId = userSender.id;
try {
if (senderId == userRecipient.id) {
res.status(406).json("You cannot have yourself as a brother")
} else {
userSender.sentBBRequests.push({senderId});
await userSender.save();
userRecipient.receivedBBRequests.push({senderId});
await userRecipient.save();
res.status(201).json("Brotheband request sent sucessfully")
}
} catch (ERR) {
res.status(500).json({ Message: ERR.message });
}
}
My test route on Postman is /add/61b29bb33e775393ae369b79
The problem is: I'm getting an error: "Cast to ObjectId failed for value \"{ senderId: '61b29aef3e775393ae369b74' }\" (type Object) at path \"sentBBRequests\
I thought maybe the problem was how I organized my Schema too:
receivedBBRequests: [
{
type: mongoose.Schema.Types.ObjectId,
},
],
sentBBRequests: [
{
type: mongoose.Schema.Types.ObjectId,
},
],
brothers: {
type: [
{
type: mongoose.Schema.Types.ObjectId,
},
]}
There are too many points of failure I can't even come up with something to solve.
Thanks a lot.
You can use the following :
const senderId = userSender._id.toString();
const userRecipientId = userRecipient._id.toString();
this will allow you to convert the objectId to string
Related
I am trying the following things:
1 Getting request body (Which is embedded with an Array).
2 Then After getting the request body I am trying to save all the objects in the array into my key of schema called "ExtraInfo".But When I run the API My "ExtraInfo" key has only object id without data.
I have Explained my whole question with my code and in my API Code, I have mentioned my logic with a comment where I am trying to push my array data to my "ExtraInfo" key.
Model:
const mongoose = require('mongoose');
const ExtraInfoModel = mongoose.Schema({
title:String,
body:String,
date: Date
})
const EmbeddedDataModel = mongoose.Schema({
class:Number,
ExtraInfo:[ExtraInfoModel],
})
module.exports = mongoose.model('EmbeddedDataCluster',EmbeddedDataModel);
RequestBody:
{
"class":"96",
"ExtraInfo":[
{
"title":"new1",
"body":"dummy1"
},
{
"title":"new2",
"body":"dummy2"
},
{
"title":"new3",
"body":"dummy3"
},
{
"title":"new4",
"body":"dummy4"
},
{
"title":"new5",
"body":"dummy5"
}
]
}
Now My Api
Router.post('/Embed', async (req, res) => {
const _ExtraInfo = await req.body.ExtraInfo;
console.log(_ExtraInfo);
try {
const _EmbeddedDataModel = await new EmbeddedDataModel({
class: req.body.class,
ExtraInfo:{$push:{$in:_ExtraInfo}}//Here is trying to loop through
//each object from array and trying to push in Key But when the Data
// saved the "ExtraInfo" key is empty and only have object id
});
_EmbeddedDataModel.save();
console.log(_EmbeddedDataModel);
res.json(_EmbeddedDataModel);
} catch (error) {
console.log(error);
res.json(error);
}
})
Result of DB:
{
"_id": "601a1f0e9fcda33570f9e26b",
"class": 96,
"ExtraInfo": [
{
"_id": "601a1f0e9fcda33570f9e26c"
}
]
}
Please Help me
I got a route in express that get 2 different array of object from mongoDb and then return a new "contributions" array after i've added some data into it from "projectAll"
Here is one contributions object:
{
_id: "5f5b095f01ba8e40769f7301",
libId: "5f5a7a7701ba8e40769f72fb",
totalPaidAmount: 10000,
transactionId: "pi_1HQ4hVGmJhXXrXOXnr0pkXkv",
cart: [
{
_id: "5f5b095f01ba8e40769f7302",
amount: 5000,
projectId: "5f5b086601ba8e40769f72fe"
},
{
_id: "5f5b095f01ba8e40769f7303",
amount: 5000,
projectId: "5f5b08ae01ba8e40769f7300"
}
],
__v: 0
}
And one projectAll object:
{
projectCover: { id: "211290" },
title: "My title 2",
funded: 11000,
description: "Desc",
_id: "5f5b08ae01ba8e40769f7300",
libId: "5f5a7a7701ba8e40769f72fb",
__v: 0
}
I need to add projectAll.title and projectAll.projectCover into each contributions.cart objects.
To do so I match contribution.cart.projectId with projectAll._id.
router.get("/contributions/:id", async (req, res) => {
const id = req.params.id
try {
const contributions = await Contribution.find({id})
const projectAll = await Project.find({id})
const updatedContribution = contributions.map((contribution) => {
// Go through each cart of each contribution
const updatedCart = contribution.cart.map((cartItem) => {
// Find matching project
const matchingProject = projectAll.find((project) => {
// project OK =====> console.log(project)
// projectAll OK =====> console.log(projectAll)
// cartItem OK =====> console.log(cartItem)
return project._id === cartItem.projectId;
});
// Here return undefined =====> console.log(matchingProject)
const {projectCover, title} = matchingProject
return {...cartItem, projectCover, title
}
})
return { ...contribution, cart: updatedCart
}
})
res.send(updatedContribution)
} catch (err) {
res.status(500).send(err)
}
this code work perfectly in my codeSandBox : https://codesandbox.io/s/contribution-map-projects-vhv8z?file=/src/index.js
But in my express + mongoose environment I get undefined for matchingProject (i added comments in the code to show from where I get unwanted result)
Does anybody know why it doesn't work ?
Thanks a lot !
EDIT: console.log(typeof project._id, typeof cartItem.projectId) return object object
whereas in codesandbox those are strings.
Since they are both ObjectIds you can use mongoose equals() functions - so project._id.equals(cartItem.projectId). You cannot compare them, cause you'd compare their object reference. So either the above function will work or project._id.toString() === cartItem.projectId.toString()
I am trying to learn how to create a Normalized many to many Post request in express/router and Mongoose.
I have three collections: User, Building and Room which is also the order of parent to child documents.
My Building document schema includes both User and Room id's as follows:
const mongoose = require('mongoose');
const BuildingSchema = new mongoose.Schema({
user: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "user"
}
],
room: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "room"
}
],
My Room document schema includes the Building ID and another child document as follows:
const mongoose = require('mongoose');
const RoomSchema = new mongoose.Schema({
building: {
type: mongoose.Schema.Types.ObjectId,
ref: "building"
},
furniture: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "furniture"
}
],
I am having trouble understanding how to create a post request that allows a user/users to create a Building instance and multiple Room instances associated with it after...
My express code so far can create a new Building instance but I am unsure how to handle including the Room id's:
router.post('/createbuilding', [auth, [
check('name', 'Building Name is required').not().isEmpty(),
]
], async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const {
name,
type,
website,
location,
bio,
} = req.body;
const buildingFields = {
user: req.user.id,
//room: req.room.id,
name,
type,
website: website && website !== '' ? normalize(website, { forceHttps: true }) : '',
location,
bio
};
try {
let building = await Building.findOneAndUpdate(
{ user: req.user.id },
//{ room: req.room.id },
{ $set: buildingFields },
{ new: true, upsert: true }
);
res.json(building);
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error');
}
}
);
Note: The references to room ID are commented out on purpose because this is what I am unsure of how to include in the Post request.
With Mongoose's .findOneAndUpdate() the first parameter is to query for the document, similar to .findOne(). Your second parameter is what fields to update. $set is redundant since Mongoose will do that for you.
If you want to add a room to the building rather than replacing all the associations, you'll want to add the room with a $push.
const buildingFields = {
$push: {
room: {
req.room.id
}
},
name,
type,
...
}
I am also assuming that you intended that the user field in BuildingSchema is a single association rather than a many associations. If not, you'd need to use a $elemMatch to query for that document:
Mongoose Mongodb querying an array of objects
I have been working with node.js and mongoose for sometime and I am hitting a wall. I have a database with 20,000 documents and when i search the database from the cli it works fine.
db.Tickets.find({ "Customers.Customer.CustomerID" : '123123123' })
This returns 256 results
Schema
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Define collection and schema for Ticket
var Ticket = new Schema({
UserName: {
type: String
},
Status: {
type: String
},
TicketNumber: {
type: Number
},
Name: {
type: String
},
Description: {
type: String
},
TicketTypeName: {
type: String
},
DueDate: {
type: Date
},
MapCollectDate : {
type: Date
},
NumberofUsersAffected : {
type: Number
},
DNNumber : {
type : String
},
RevisionDate : {
type : Date
},
CommercialImpact : {
type: String
},
Customers :[{
Customer: [{
CustomerID: Number,
CustomerName: String
}]
}],
Although if I test this in node.js using mongoose. I can't get it to return anything
I have a generic search that works
Ticket.find(function (err, tickets){
But can't get the specific search to work.
I am Connecting to Mongo
const config = require('./db');
//const Course = require('./models/Course');
//const CourseRoute = require('./routes/CourseRoute');
const Ticket = require('./models/Ticket');
const TicketRoute = require('./routes/TicketRoute');
const PORT = 4000;
mongoose.connect(config.DB).then(
() => {console.log('Connected to MongoDB') },
err => { console.log('Error connecting to MongoDB' +err)
});
Output of the log
Your node js server is running on PORT: 4000
Connected to MongoDB
Connected to MySQL
My Route End point
router.route('/').get(function (req, res) {
Ticket.find({ "Customers.Customer.CustomerID" : global.auth_username }, function(err, ticket) {
if(err){
console.log(err);
}
else {
res.json(tickets);
}
});
});
Also tried without the variable
router.route('/').get(function (req, res) {
Ticket.find({ "Customers.Customer.CustomerID" : "123123123" }, function(err, ticket) {
if(err){
console.log(err);
}
else {
res.json(tickets);
}
});
});
I had the same issue when I forgot to connect to Mongoose before running query
mongoose.connect(MONGO_URL, mongoOptions)
.then(() => {
// do your thing here
})
You had over a year to figured this out, and I am sure that you did so, but either way it seems that you have a typo in your code. The callback parameter is named ticket - function(err, ticket) {, whereas you are logging tickets - res.json(tickets);. In the generic test you correctly wrote tickets - Ticket.find(function (err, tickets){, which is probably why it worked.
The takeaway lesson here is - use debugging tools instead of logging, makes it easier to catch such problems.
Also, it would be appropriate to answer your own question once you've figured it out. But given that this is probably completely useless, you might as well delete it. Cheers!
I have a simple model, which is:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var citySchema = new Schema({
name: { type: String, required: true },
state: { type: Schema.Types.ObjectId, ref: 'State' }
});
module.exports = mongoose.model('City', citySchema);
Only i access a route, asking to insert a city, giving as post params
POST: {
name: 'My City',
state: 'SE' // Stands for Some State
}
I know the type of the state property is not correct, but in my logic i do:
var newCity = new City(req.body);
if (typeof req.body.state !== 'undefined' && req.body.state.length == 2) {
State.findOne({uf: req.body.state.toUpperCase()}, function(err, foundState) {
if (err) { res.send({status: 500, message: 'Could not find the required state'}); return; }
newCity.state = foundState._id;
newCity.set('state', foundState._id);
return;
});
}
But, once i do a res.send(newCity), to check out the newCity variable properties, it prints:
{
"name": "Balneário Camború",
"_id": "570ff2944c6bd6df4e8e76e8"
}
And if i try to save it, i get the following error:
ValidationError: CastError: Cast to ObjectID failed for value \"SE\" at path \"state\""
So, i'm quite confused, because when the Model is created using the req.body properties, it does not list the state property, even if i set it later in the code, but when i try to save the City, it throw an error of mistype.
What could be causing this, and how should i procede?