MongoDB API from express - javascript

Have a model
const mongoose = require("mongoose");
const botSchema = new mongoose.Schema({
code: {
type: String,
required: true,
unique: true,
},
description: {
type: String,
required: true,
},
botStatus: {
type: String,
required: true,
},
});
// botSchema.plugin(require("mongoose-beautiful-unique-validation"));
module.exports = mongoose.model("Bot", botSchema);
route =====
// Creating one
router.post("/", async (req, res) => {
const bot = new Bot({
code: req.body.code,
description: req.body.description,
botStatus: req.body.botStatus,
});
try {
const newBot = await bot.save();
res.status(201).json(newBot);
} catch (err) {
res.status(400).json({ message: err.message });
}
});
==== when post using postman or Rest Client from VS Code
POST http://localhost:4000/bots
Content-Type: application/json
{
"code": "code 04",
"description": "desc 04",
"botStatus": "status 04"
}
it gives me the error
{
"message": "E11000 duplicate key error collection: botmanager.bots index: route_id_1 dup key: { route_id: null }"
}
I have no ideas where is route_id_1 dup key is coming from

Related

Mongoose mixed Type object array, can findOneAndUpdate

I have a controller edit card which updates the fields of cardsArray object.
cardsArray is mixed type object as fileds of each card object is different so i am storing mixed.type
Althought pushing new card using addCard controller works perfectly
But when edit card controller is called, it gives type error
When edit Controlller is callled is gives following error:
TypeError: Cannot read properties of null (reading 'cardsArray')
// Schema
const userSchema = new mongoose.Schema(
{
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
cardsArray: [{ type: mongoose.Schema.Types.Mixed }],
}
);
//__Mongodb Data
{
"_id": {
"$oid": "63b43ab32fc8d3c100cafecc"
},
"name": "usern_name",
"email": "pr****#gmail.com",
"password": "$2b$12$3nwifHakrBu94BwLXAC4Nu16Kw0.xyW8vAIPTMSgY7cYttVklDIZq",
"cardsArray": [
{
"title": "some_title",
"category": "Bank",
"cardHolder": "some_name",
"cardNumber": "54545454",
"expiry": "23/01",
"cvv": "***",
"logoIndex": 72,
"isFavourite": false,
"_id": {
"$oid": "63b83cc77288d277ef359533"
}
}
],
"loginIdsArray": [],
"docsArray": [],
"activitiesArray": [],
"__v": 0
}
// Add Card Controller.js___
addCard: async (req, res) => {
console.log(req.body.data, req.body.user_id)
// console.log('obj_id', newObjectId)
req.body.data._id = newObjectId;
try {
const response = await UserDatabase.findOneAndUpdate(
{ _id: req.body.user_id },
{
$push: {
// cardsArray: req.body.data,
cardsArray: { $each: [req.body.data] },
},
},
{ returnOriginal: false }
);
res.status(200).send(response);
} catch (error) {
console.log(error)
res.status(404).json({ message: error.message });
}
},
// edit card controller.js
editCard: async (req, res) => {
const id = req.params.id;
const { category, title, cardHolder, cardNumber, expiry, cvv, logoIndex, isFavourite } = req.body;
console.log(req.params.id)
try {
const response = await UserDatabase.findOneAndUpdate(
{ _id: "63b43ab32fc8d3c100cafecc", 'cardsArray._id': "63b709fc69a1cfa6fccd645c" },
{
$set: {
"cardsArray.$.title": req.body.title,
"cardsArray.$.category": req.body.category,
"cardsArray.$.cardHolder": req.body.cardHolder,
"cardsArray.$.cardNumber": req.body.cardNumber,
"cardsArray.$.expiry": req.body.expiry,
"cardsArray.$.cvv": req.body.cvv,
"cardsArray.$.logoIndex": req.body.logoIndex,
"cardsArray.$.isFavourite": req.body.isFavourite
}
},
);
console.log(response)
res.status(201).json(response.cardsArray);
} catch (error) {
console.log(error)
res.status(404).json({ message: error.message });
}
}
it means that there is no data matching the following _id and cardsArray._id
i thinks so its fails to find the feild 'cardsArray._id',first try finding the value by just findOne
await UserDatabase.findOneAndUpdate(
{ _id: "63b43ab32fc8d3c100cafecc", 'cardsArray._id': "63b709fc69a1cfa6fccd645c" })
if your find doesn't work try below methord not sure but it may work you have to either find the id and loop through the cardsArray of use $in or $match
await UserDatabase.findOneAndUpdate(
{ _id: "63b43ab32fc8d3c100cafecc", 'cardsArray':{$in:[ {_id:"63b709fc69a1cfa6fccd645c" }]})

node.js moongose find populate cant access to array

I have this in my backend:
ad = await Ad.find({'company': companyId}).populate('creator');
And when i console.log(ad) i get this:
[
{
connections: [],
status: 1,
_id: 6047c711b1f8cf1c98b2227c,
title: "DOTA: Dragon's Blood | Teaser | Netflix",
company: 6047c6fab1f8cf1c98b2227a,
video: 'uploads\\videos\\7802d640-810a-11eb-83c2-57e23ae6d491.mp4',
creator: {
companies: [Array],
ads: [Array],
_id: 6047c6e7b1f8cf1c98b22279,
name: 'test test',
email: 'test#live.com',
image: 'uploads\\images\\5f3ea850-810a-11eb-83c2-57e23ae6d491.jpeg',
password: '',
__v: 3
},
__v: 0
},
{
connections: [ 6047c745b1f8cf1c98b22280, 6047c83bb1f8cf1c98b22286 ],
status: 1,
_id: 6047c72cb1f8cf1c98b2227f,
title: 'Diretide 2020',
company: 6047c6fab1f8cf1c98b2227a,
video: 'uploads\\videos\\87a97d60-810a-11eb-83c2-57e23ae6d491.mp4',
creator: {
companies: [Array],
ads: [Array],
_id: 6047c6e7b1f8cf1c98b22279,
name: 'test test',
email: 'test#live.com',
image: 'uploads\\images\\5f3ea850-810a-11eb-83c2-57e23ae6d491.jpeg',
password: '',
__v: 3
},
__v: 6
}
]
But when i try to console.log(ad.creator) or console.log(ad.creator.ads) im getting undefined error.. I need this becasue i want to pull some things from ad.creator.ads..
Do i miss something in my code?
I will try to be more specific i tried but i cant figure how to do this:
ad.js:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const adSchema = new Schema({
title: { type: String, required: true },
description: { type: String, required: true },
video: { type: String, required: true },
company: { type: mongoose.Types.ObjectId, required: true, ref: 'Company' },
creator: { type: mongoose.Types.ObjectId, required: true, ref: 'User' },
connections: [{type: mongoose.Schema.ObjectId, ref: 'User'}],
status: {type: Number, default: '1'}
});
module.exports = mongoose.model('Ad', adSchema);
So i need here when i delete this company to also pull all companies from user..
This is user.js
const mongoose = require('mongoose');
const uniqueValidator = require('mongoose-unique-validator');
const Schema = mongoose.Schema;
const userSchema = new Schema({
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true, minlength: 6 },
image: { type: String, required: true },
companies: [{ type: mongoose.Types.ObjectId, required: true, ref: 'Company' }],
ads: [{ type: mongoose.Types.ObjectId, required: true, ref: 'Ad' }]
});
userSchema.plugin(uniqueValidator);
module.exports = mongoose.model('User', userSchema);
process for deleting company in // i specified part with problem where need to pull ads from user for this:
const deleteCompany = async (req, res, next) => {
const companyId = req.params.cid;
let company;
let ad;
try {
company = await Company.findById(companyId).populate('creator');
ad = await Ad.find({'company': companyId}).populate('creator');
} catch (err) {
const error = new HttpError(
'backend_message13',
500
);
return next(error);
}
if (!company) {
const error = new HttpError('backend_message14', 404);
return next(error);
}
if (company.creator.id !== req.userData.userId) {
const error = new HttpError(
'backend_message15',
401
);
return next(error);
}
const imagePath = company.image;
try {
const sess = await mongoose.startSession();
sess.startTransaction();
await company.remove({ session: sess });
company.creator.companies.pull(company);
await company.creator.save({ session: sess });
// here is the path where is problem i also tried with ad[0]
ad.creator.pull(ad.creator.ads);
await ad.creator.save({ session: sess });
//
await Ad.deleteMany({'company': companyId});
await sess.commitTransaction();
} catch (err) {
const error = new HttpError(
err,
500
);
return next(error);
}
fs.unlink(imagePath, err => {
console.log(err);
});
ad.forEach(function (item) {
const videoPath = item.video;
const thumb = item.video.replace("uploads\\videos\\","uploads\\videos\\thumb\\").replace(".mp4", "_screenshot.jpeg");
fs.unlink(videoPath, err => {
console.log(err);
});
fs.unlink(thumb, err => {
console.log(err);
});
});
res.status(200).json({ message: 'backend_message17' });
};
Thanks for help :)
append lean() mean on populate and then see
ad = await Ad.find({'company': companyId}).populate('creator').lean();
The query Ad.find() returns an array - but your code tried to access it as an object:
ad = await Ad.find({'company': companyId}).populate('creator');
console.log(ad.creator)
ad.creator actually is an undefined
Use an index to access required array element:
ad = await Ad.find({'company': companyId}).populate('creator');
console.log(ad[0].creator)
Or switch to Ad.findOne()

Find One and Update in Mongoose with reference to other models is not working

I have a model named OrderModel and it has reference to other models as well
const orderSchema = new Schema({
_id: Schema.Types.ObjectId,
address: { type: addressSchema, required: false },
items: [{ type: Schema.Types.ObjectId, ref: 'Items' }],
date: { type: Date, default: moment(new Date()) },
user: { type: Schema.Types.ObjectId, ref: 'Users' },
is_completed: { type: Boolean, required: true, default: false },
is_canceled: { type: Boolean, required: true, default: false }
});
and when I want to update this model, using PATCH, it is giving me an error,
CastError: Cast to [ObjectId] failed for value "["5f0c9493f833e23a0028bd31,5f0c9429f833e23a0028bd2f"]" at path "items"
Here is how I do it in my code,
router.patch('/order', (req, res) => {
const query = { _id: req.body._id };
const _token = req.headers.authorization;
let data = req.body;
jwt.verify(_token, process.env.AUTH_TOKEN_KEY, (err, decoded) => {
console.log(query);
if (err) {
res.json({ message: 'Token Invalid'.err });
} else {
OrderModel.findOneAndUpdate(query, data, { new: true }, (err, doc) => {
console.log(doc,query);
if (doc) {
return res.json({ message: 'Succesfully saved', data: doc });
}
return res.json({ message: `No order found for id ${req.body._id}` });
});
}
})
})
i have two items as an Array, sent from frontend
{
"_id": "5f8f1b7b29cbed4a8495d646",
"items":"5f0c9493f833e23a0028bd31,5f0c9429f833e23a0028bd2f",
"user":"5f06060110b7881ac0244005",
"address":{
"line_1": "Address line 1",
"line_2": "Address line 1",
"city": "Los Angeles",
"state": "California",
"pin": "90210"
},
"is_completed": false,
"is_canceled": false
}
what am i doing wrong here?

TypeError: Order.find is not a function

I am building ecommerce website using MERN stack. And I am getting error while testing using Postman.
backend/controllers/user.js
const User = require("../models/user");
const Order = require("../models/order");
exports.userPurchaseList = (req, res) => {
Order.find({ user: req.profile._id })
.populate("user", "_id name")
.exec((err, order) => {
if (err) {
return res.status(400).json({
error: "No Order in this account",
});
}
return res.json(order);
});
};
backend/models/Order.js
const mongoose = require("mongoose");
const { ObjectId } = mongoose.Schema;
const ProductCartSchema = new mongoose.Schema({
product: {
type: ObjectId,
ref: "Product",
},
name: String,
count: Number,
price: Number,
});
const ProductCart = mongoose.model("ProductCart", ProductCartSchema);
const OrderSchema = new mongoose.Schema(
{
products: [ProductCartSchema],
transaction_id: {},
amount: { type: Number },
address: String,
status: {
type: String,
default: "Recieved",
enum: ["Cancelled", "Delivered", "Shipped", "Processing", "Recieved"],
},
updated: Date,
user: {
type: ObjectId,
ref: "User",
},
},
{ timestamps: true }
);
const Order = mongoose.model("Order", OrderSchema);
module.exports = { Order, ProductCart };
backend/models/User.js
const mongoose = require("mongoose");
const crypto = require("crypto");
const uuidv1 = require("uuid/v1");
var userSchema = new mongoose.Schema(
{
name: {
type: String,
required: true,
maxlength: 32,
trim: true,
},
lastname: {
type: String,
maxlength: 32,
trim: true,
// required: false,
},
email: {
type: String,
required: true,
trim: true,
unique: true,
},
userinfo: {
type: String,
trim: true,
},
encry_password: {
type: String,
required: true,
},
salt: String,
role: {
type: Number,
default: 0,
},
purchases: {
type: Array,
default: [],
},
},
{ timestamps: true }
);
module.exports = mongoose.model("User", userSchema);
backend/routes/user.js
router.get(
"/orders/user/:userId",
isSignedIn,
isAuthenticated,
userPurchaseList
);
Error:-
TypeError: Order.find is not a function
at exports.userPurchaseList (C:\Users\Rahul\MernBootcamp\projbackend\controllers\user.js:47:9)
TESTING this route using POSTMAN.
You have exported an object so in your backend/controllers/user.js
you could import it like so from destructuring from the object then the rest of your code would be okay
const {Order} = require("../models/order");
or
accessing it using the dot notation
when calling the find Function
//importing it at the top
const Order = require("../models/order");
exports.userPurchaseList = (req, res) => {
Order.Order.find({ user: req.profile._id })
.populate("user", "_id name")
.exec((err, order) => {
if (err) {
return res.status(400).json({
error: "No Order in this account",
});
}
return res.json(order);
});
};

E11000 duplicate key error collection:

The following piece of code which works fine. However,when I run it again from my cmd(node server),I get a duplicate key message of the dish name. I have two files. The dishes.js where I define my schemas and make available to my second file called server.js.
dishes
// grab the things we need
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var commentSchema = new Schema({
rating: {
type: Number,
min: 1,
max: 5,
required: true
},
comment: {
type: String,
required: true
},
author: {
type: String,
required: true
}
}, {
timestamps: true
});
// create a schema
var dishSchema = new Schema({
name: {
type: String,
required: true,
unique: true
},
description: {
type: String,
required: true
},
comments:[commentSchema]
},
{
timestamps: true
});
// the schema is useless so far
// we need to create a model using it
var Dishes = mongoose.model('Dish', dishSchema);
// make this available to our Node applications
module.exports = Dishes;
and my server.js file.
var mongoose = require('mongoose'),
assert = require('assert');
var Dishes = require('./models/dishes-3');
// Connection URL
var url = 'mongodb://localhost:27017/conFusion';mongoose.connect(url);
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function () {
// we're connected!
console.log("Connected correctly to server");
// create a new dish
Dishes.create({
name: 'Uthapizza',
description: 'Test',
comments: [
{
rating: 3,
comment: 'This is insane',
author: 'Matt Daemon'
}
]
}, function (err, dish) {
if (err) throw err;
console.log('Dish created!');
console.log(dish);
var id = dish._id;
// get all the dishes
setTimeout(function () {
Dishes.findByIdAndUpdate(id, {
$set: {
description: 'Updated Test'
}
}, {
new: true
})
.exec(function (err, dish) {
if (err) throw err;
console.log('Updated Dish!');
console.log(dish);
dish.comments.push({
rating: 5,
comment: 'I\'m getting a sinking feeling!',
author: 'Leonardo di Carpaccio'
});
dish.save(function (err, dish) {
console.log('Updated Comments!');
console.log(dish);
db.collection('dishes').drop(function () {
db.close();
});
});
});
}, 3000);
});
});
If you pay a close attention in the server.js file I have removed the unique: true attribute from by dishes.js file,but I still have the same problem.
name: {
type: String,
required: true,
unique: true
},
when your schema is given below
name: {
type: String,
required: true,
unique: true
}
the unique is working
when your schema is given below
name: {
type: String,
required: true
}
the unique not working
after change your schema definition, drop all your collection and try to insert.

Categories