how to query with out [0] in mongoose? - node.js

I'd like to make a query that moves ytbReqTb's data to ytbChannelTb.
This is my Schema(ytbReqTb)
const ytbReqTbSchema = new Schema({
_id: mongoose.Schema.Types.ObjectId,
ytbChannel: String,
ytbSubscribe: Number,
ytbHits: Number
}
and this is my other Schema(ytbChannelTb).
{
const ytbChannelTbSchema = new Schema({
_id: mongoose.Schema.Types.ObjectId,
ytbChannel: String,
ytbSubscribe: Number,
ytbHits: Number,
}
So I query like this and it works.
router.put('/recognize/:youtuber', async (req, res, next) => {
const ytbReq = await YtbReqTb.find({ 'ytbChannel' : req.params.youtuber });
await YtbReqTb.remove({ 'ytbChannel' : req.params.youtuber });
const ytbChannelTb = new YtbChannelTb({
_id: new mongoose.Types.ObjectId(),
ytbChannel: ytbReq[0].ytbChannel,
ytbSubscribe: ytbReq[0].ytbSubscribe,
ytbHits: ytbReq[0].ytbHits,
});
ytbChannelTb.save()
.then(result => {
res.status(201).json();
})
.catch(err => {
console.log(err);
res.status(500).json({
error: err
});
});
});
But it doesn't work without '[0]'. Is there a way to query without '[0]'?
If query can't take out '[0]', could you tell me why?

the result of find is a array, if you want result be an object so use findOne instead of find like this:
const ytbReq = await YtbReqTb.findOne({ 'ytbChannel' : req.params.youtuber });

Related

Error while updating mongo db object by id

I am trying to update my mongodb database by Id but I am getting error userId.save is not a function. What I did was get all the databases data by Object.findById then used Object.assign to assign an updated value to the specified key then saved the updated Object back to the database. Where did I go wrong. How can I update a mongodb object by Id. Thanks in advance.
const Users = require('pathToSchema')
const userId = Users.findById('ObjectId')
Object.assign(userId, '{"email": "test#gmail.com"}')
//error arrises here. "userId.save is not a function"
userId.save()
.then((result) => {
console.log(result)
})
.catch((err) => {
console.log(err)
})
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const users_Schema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
}
}, {timestamps: true})
const Users = mongoose.model('users', users_Schema)
module.exports = Users;
The findById is not execute yet. You have to use it with a callback or an exec(). You can learn more at mogoose doc.
Try change line const userId = Users.findById('ObjectId') to const userId = await Users.findById('ObjectId').exec(). exec() will return a promise, so you could use await to get result.
Furthermore, the Object.assign statement is not correct, there is no need for the string character (which is '). It's just Object.assign(userId, {"email": "test#gmail.com"})
Try assigning the email prop instead of using Object.assign. Also bear in mind that you need to assign 2 objects but you assign a string instead.
Try this:
const userId = await Users.findById('ObjectId')
userId.email = 'test#gmail.com';
userId.save()
.then((result) => {
console.log(result)
})
.catch((err) => {
console.log(err)
})
Also, make sure you create a model from the schema and use it to findById. For instance:
const UserSchema = new Schema({
name:String,
username:{type:String, required:true, index:{unique:true}},
password:{type:String, required:true, select:false}
});
const UserModel = mongoose.model('User', UserSchema);
const user = await UserModel.findById(...);
user.save();
This worked for me.
Users.findById('ObjectId')
.then((result) => {
Object.assign(result, {
"email": "test#gmail.com"
})
result.save()
.then((result) => {
console.log(result)
})
.catch((err) => {
console.log(err)
})
})
.catch((err) => {
console.log(err)
})

not able to save array of ids mongo

I have an Order model that looks like this
const mongoose = require('mongoose');
const orderSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
products: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Product', required: true }]
});
module.exports = mongoose.model('Order', orderSchema);
This is the OrderController:
exports.orders_create_order = (req, res, next) => {
console.log("======This is what we're sending to the endpoint==============================");
console.log(req.body);
console.log('====================================');
const order = new Order({
_id: mongoose.Types.ObjectId(),
products: req.body.products
});
order.save().then(result => {
console.log('====================================');
console.log("This is what is getting saved");
console.log(result);
console.log('====================================');
res.status(201).json({
message: "Order stored",
createdOrder: {
_id: result._id,
products: result.product
}
});
})
.catch(err => {
console.log(err);
res.status(500).json({
error: err
});
});
};
It takes an array of objects that I am sending from the a react frontend like so:
axios.post("http://ocalhost:4500/orders/", {"products":"[5e9e7edb4e0e5100041e3aa1, 5e9e85824e0e5100041e3aa4, 5e9e859d4e0e5100041e3aa6]"})
.then(res => {
console.log('=======This is the data we are getting from saving new wishlist at the frontend=============================');
console.log(res.data);
console.log('====================================');
})
.catch(err =>
console.log(`The error we're getting from the backend--->${err}`))
the error I am getting here is :
message: 'Cast to Array failed for value "[5e9e7edb4e0e5100041e3aa1, 5e9e85824e0e5100041e3aa4, 5e9e859d4e0e5100041e3aa6]" at path "products"',
Please tell me what am I doing wrong here?
You are tring to send products as string, it should be an array like this:
{
"products": [
"5e9e7edb4e0e5100041e3aa1",
"5e9e85824e0e5100041e3aa4",
"5e9e859d4e0e5100041e3aa6"
]
}

Node express find and return response multple models

I'm fairly new to node & express, I'm trying to implement a register application.
I have 2 models, both models have one common field 'empID'.
const RegisterEntriesSchema = mongoose.Schema({
empID: Number,
registerType: String,
registerItemsQuantity: Number,
registerItemsDesc: String
}, {
timestamps: true
});
const RegisterEmpSchema = mongoose.Schema({
empID: Number,
empName: String,
empPhone: String,
empProj:String
}, {
timestamps: true
});
For my get call in which I need to merge the values, I get from RegisterEmpSchema with its corresponding
employee details from RegisterEmpSchema.
exports.findAllRegisterEntries = (req, res) => {
registerEntriesModel.find()
.then(result => {
var updatedResponse=[];
console.log(result[0].empID);
for(var i=0;i<result.length;i++){
registerEmpModel.find({ empID: result[i].empID })
.then(result2 => {
**//unable to access result here**
}).catch(err => {
console.log("exception catch called findAllRegisterEntries, find employee details "+err);
});
}
res.send(updatedResponse);
}).catch(err => {
res.status(500).send({
message: err.message || "Some error occurred while retrieving register."
});
});
};
I basically need to get register data and its corresponding employee data.
How do I modify my find() code to use the key empID and do a join query fetch?
I think you better use populate, add ref to empID inside RegisterEntriesSchema
const RegisterEmpSchema = new mongoose.Schema({
empID: Number,
empName: String,
empPhone: String,
empProj: String
}, {
timestamps: true
});
const registerEmpModel = mongoose.model('RegisterEmpSchema', RegisterEmpSchema, 'registerEmployeeCollection');
const RegisterEntriesSchema = new mongoose.Schema({
registerType: String,
registerItemsQuantity: Number,
registerItemsDesc: String,
empID: {
type: mongoose.Schema.Types.ObjectId,
ref: 'RegisterEmpSchema'
}
}, {
timestamps: true
});
RegisterEntriesSchema.index({ createdAt: 1 }, { expires: '525601m' });
const registerEntriesModel = mongoose.model('RegisterEntriesSchema', RegisterEntriesSchema, 'registerEntriesCollection');
module.exports = {
registerEmpModel, registerEntriesModel,
}
then use populate() to populate the RegisterEntriesSchema with correspondence empID
RegisterEntriesSchema.
find().
populate('empID').
exec(function (err, data) {
if (err) return console.log(err);
res.send(data);
});
check mongoose docs: https://mongoosejs.com/docs/populate.html

cast to objectId failed for value xxx

I am using mongoDB populate model and when I try to save the data inside the schema it throws an error:
message: 'Cast to ObjectId failed for value
this is my schema
jobSiteInformation: {
buildingName: String,
street: String,
city: String,
},
data: [{
ref: 'data',
type: Schema.Types.ObjectId,
required: true,
}],
phase schema is like this
const listSchema= new Schema({
name: String,
progress: Number,
list: [],
});
this phase schema is array inside phases which is the quite large and thats the reason I moved to populate model.
anyway this is my route and when I run this it throws the error I pasted above.
router.post('/', async (req, res, next) => {
const info= new List({
jobSiteInformation: req.body.jobSiteInformation,
});
try {
const install = req.body.list;
install.map((inst) => info.lists.push(inst));
const saved= await partial.save();
return res.status(201).json({
result: saved,
});
} catch (e) {
console.log(e);
return next(e);
}
});
I have tried to google but I cannot find the what I am looking for. I have read other posts too but cannot understand what I am doing wrong here.
Assuming mongoose model for phase schema is Phase
// import Phase from ../models/phase
router.post('/request/partial', async (req, res, next) => {
const partial = new PartialRequest({
jobSiteInformation: req.body.jobSiteInformation,
});
try {
const install = req.body.installations;
let savedPhases = await Phase.insertMany(install); // TODO: handle error case
savedPhases.map((inst) => partial.installations.push(inst["_id"]));
const savedPartials = await partial.save();
console.log(savedPartials);
return res.status(201).json({
result: savedPartials,
});
} catch (e) {
console.log(e);
return next(e);
}
});

Cascade Delete in mongo

I am new to MongoDB. I created 4 collections & they are connected with each other. (I am using node.js to write it)
Here, it's my question. How can I delete all records at once? Is there something like deep level population?
This one holds all models.
const DataModel = mongoose.Schema({
_id: { type: mongoose.Schema.Types.ObjectId, ref: 'User', require: true},
order: { type: mongoose.Schema.Types.ObjectId, ref: 'Order', require: true},
});
User model
const userSchema = mongoose.Schema({//other stuff});
Order model
const orderSchema = mongoose.Schema({
product: { type: mongoose.Schema.Types.ObjectId, ref: 'Product', required: true },
//other stuff
});
Product model
const productSchema = mongoose.Schema({//other stuff});
I can delete the entry with these code from the database, but the other entries still there
exports.delete_data = (req, res, next) => {
const id = req.params.userId;
userDataModel.deleteOne({_id: id})
.exec()
.then(docs => {
res.status(200).json({
message: 'Record Deleted',
request: {
type: 'POST'
}
});
})
.catch(err => {
console.log(err);
res.status(500).json({
error: err
});
});
};
Update: However, I wonder, Could I call other defined delete functions for order, product inside delete_data
As #Geert-Jan suggest, cascade delete is my solution. The link that geert-jan gave solve my problem. However, I wonder, Could I call other defined delete functions for order, product inside delete_data
i did this and it could be good for someone who wants to delete documents in cascade linked to any field of a model.
async blackHole() {
try {
const rtn = new ApiResponse<any>();
const userId = id;
const accountId = mongoose.Types.ObjectId(id);
var CollectionNames: any[] = [];
mongoose.connection.db.listCollections().toArray(function (err, collections) {
CollectionNames = collections.map(c => c.name);
CollectionNames.forEach((element: any) => {
mongoose.connection.db.collection(element).deleteMany({ "account": accountId });
});
});
const accountController = new AccountController(this.wsParams);
await accountController.delete(id)
await super.delete(userId);
return rtn;
} catch (error: any) {
const rtn = new ApiResponse<any>();
rtn.message = error;
rtn.success = false;
rtn.status = 422;
return rtn;
}
}
I hope you can use it :D

Resources