How to get data by dynamic collection name in nodejs and mongoose - node.js

Tried to get data from table by passing collection name dynamically but not working.I have two table[shoptable and markettable] and same header data.I want to get data depends on passing collection name.I do not know how to set schema for dynamic collection.Anyone can find wher i did mistake?
table.controller.js //Nodejs
const mongoose = require('mongoose');
const _ = require('lodash');
var Schema = mongoose.Schema;
let dynamicModels = {};
const ConvForUserSchema = new Schema({
product_name: {
type: String
},
price: {
type: String
},
catogery: {
type: String
}
}, {
versionKey: false,
strict: false
});
const dynamicModel = (collectionName) => {
if (!(collectionName in dynamicModels)) {
dynamicModels[collectionName] = mongoose.model(collectionName, ConvForUserSchema, collectionName);
}
return dynamicModels[collectionName];
};
module.exports.getTableData = (req, res, next) => {
let collection = req.query.collection;
console.log("col=" + collection)
dynamicModel(collection).find({}, function(err, docs) {
if (err) {
console.log('ss' + err);
return
}
return res.json(docs);
})
}
user.service.ts:
getTableData(collection){
return this.http.get(`http://localhost:3000/api/getTableData?collection=${collection}`);
}
product.component.js:
shopDatas(){
this.getProductsData('shoptable');
}
marketDatas(){
this.getProductsData('markettable');
}
getProductsData(collection){
this.userService.getTableData(collection).subscribe(
res => {
this.tableData = res;
},
err => {
console.log(err);
}
);
}
product.component.html:
<button (click)="shopDatas()">Shop data</button>
<button (click)="marketDatas()">Market data</button>

const newCollection = mongoose.model("collectionName" , Schema)
newCollection.find({} , (err, docs)=>{
console.log(docs)
})

Related

Code executes before i get the response from the database

I am new to Express and writing the code to get the list from my database. I'm trying to update the quantity of the items in my list. Now there can be multiple items and quantity for those items needs to be updated accordingly. The problem I am facing is when I try to get the list and update item accordingly, before my for loop executes to update the item it doesn't update the item's quantity in the database and saves the order. What am I doing wrong?
I have used async functions, promises and flags to update the items quantity in the database but none helps.
This is my code for to get and update the item's quantity
const Express = require("express");
const app = Express.Router();
const Menu = require("../../models/Menu");
const Order = require("../../models/order");
const User = require("../../models/user");
app.post(
"/create",
async function(req, res) {
var myorder = {};
var orderList = [];
var ordDetail = [];
var UpdateMenus = [];
orderList = JSON.parse(JSON.stringify(req.body["OD"]));
if(orderList.length>0){
const user = await User.findOne({ _id: req.user.id })
.then(user => {
if (!user) {
return res.status(400).json({ error: "User Not Found" });
}
})
.then(() => {
var order = Order({
user: req.user.id
});
myorder = order;
(async function loop() {
for (i = 0; i < orderList.length; i++) {
const ordt = new Object({
menu: orderList[i]["menuId"],
order: myorder.id,
prize: orderList[i]["prize"],
quantity: orderList[i]["quantity"]
});
await Menu.findOne({ _id: orderList[i]["menuId"] })
.exec()
.then(menu => {
if (menu) {
if (menu.quantity >= ordt.quantity) {
menu.quantity = menu.quantity - ordt.quantity;
const editmenu = menu;
(async function updateTheMenu() {
await Menu.findOneAndUpdate(
{ _id: menu.id },
{ $set: editmenu },
{
new: true,
useFindAndModify: false
}
).then(updateMenu => {
console.log(updateMenu);
ordDetail.push(ordt);
});
})();
} else {
return res.status(400).json({
error:
menu.MenuText +
"" +
ordt.quantity +
" Qunatity Is Not Available"
});
}
}
});
}
})();
}).then(()=>{
order
.save()
.then(order => {
if (!order) {
return res.json({ error: "Order is not saved" });
}
res.status(200).json(order);
})
.catch(error => {
return res
.status(400)
.json({ error: "Fields are Not Correct" });
});
});
}
}
);
There are few things wrong with your code:
If you use await then you don't need to use then. You can just assign to a variable. Example:
const menu = await Menu.findOne({ _id: orderList[i]["menuId"] })
You don't need to wrap your loop and every await call in async functions. They are already in an async function.
You can write your response handler like this:
app.post('/create', async function(req, res) {
var myorder = {};
var orderList = [];
var ordDetail = [];
var UpdateMenus = [];
orderList = JSON.parse(JSON.stringify(req.body['OD']));
if (orderList.length > 0) {
const user = await User.findOne({ _id: req.user.id });
if (!user) {
return res.status(400).json({ error: 'User Not Found' });
}
var order = Order({
user: req.user.id
});
myorder = order;
for (i = 0; i < orderList.length; i++) {
const ordt = new Object({
menu: orderList[i]['menuId'],
order: myorder.id,
prize: orderList[i]['prize'],
quantity: orderList[i]['quantity']
});
const menu = await Menu.findOne({ _id: orderList[i]['menuId'] });
if (menu) {
if (menu.quantity >= ordt.quantity) {
menu.quantity = menu.quantity - ordt.quantity;
const editmenu = menu;
const updateMenu = await Menu.findOneAndUpdate(
{ _id: menu.id },
{ $set: editmenu },
{
new: true,
useFindAndModify: false
}
);
console.log(updateMenu);
ordDetail.push(ordt);
} else {
return res
.status(400)
.json({
error:
menu.MenuText +
'' +
ordt.quantity +
' Qunatity Is Not Available'
});
}
}
}
try {
const savedOrder = await order.save();
if (!savedOrder) {
return res.json({ error: 'Order is not saved' });
}
res.status(200).json(savedOrder);
} catch (error) {
return res.status(400).json({ error: 'Fields are Not Correct' });
}
}
});

Seeding mongoDB data in node.js by referencing ObjectId

i'm using mongoose-data-seed to seed data into mongodb, however it has no mechanism to allow passing of ObjectId() as references to other seed files
I found a way to store the output of each of the seeders in a json file and retrieve the ObjectIds from the previous seeds to use in the current seeder. This way i can reference ObjectIds from previous seeders.
seeding-helper.js
const fs = require('fs');
// const path = require('path');
const seedersTmpDataFolder = 'seeders/bin';
class SeedingHelper {
static saveData(filename, data) {
return new Promise((resolve) => {
fs.writeFile(`${seedersTmpDataFolder}/${filename}.json`, JSON.stringify(data, null, '\t'), (err) => {
if (err) throw err;
resolve();
});
});
}
static readData(filename) {
return new Promise((resolve) => {
fs.readFile(`${seedersTmpDataFolder}/${filename}.json`, 'utf8', (err, data) => {
if (err) throw err;
resolve(JSON.parse(data));
});
});
}
}
module.exports = SeedingHelper;
resourceActions.seeder.js
const { Seeder } = require('mongoose-data-seed');
const mongoose = require('mongoose');
const ResourceAction = require('../models/resourceAction');
const SeedingHelper = require('../helpers/seeding-helper');
const { Types: { ObjectId } } = mongoose;
const data = [
{
_id: ObjectId(),
name: 'test1'
},
{
_id: ObjectId(),
name: 'test2'
},
];
class ResourceActionSeeder extends Seeder {
async shouldRun() { // eslint-disable-line class-methods-use-this
return ResourceAction.count().exec().then(count => count === 0);
}
async run() { // eslint-disable-line class-methods-use-this
let result;
await SeedingHelper.saveData('resourceActions', data)
.then(() => {
result = ResourceAction.create(data);
});
return result;
}
}
module.exports = ResourceActionSeeder;
resources.seeder.js
const { Seeder } = require('mongoose-data-seed');
const mongoose = require('mongoose');
const Resource = require('../models/resource');
const SeedingHelper = require('../helpers/seeding-helper');
const { Types: { ObjectId } } = mongoose;
class ResourcesSeeder extends Seeder {
async shouldRun() { // eslint-disable-line class-methods-use-this
return Resource.count().exec().then(count => count === 0);
}
async run() { // eslint-disable-line class-methods-use-this
let result;
await SeedingHelper.readData('resourceActions')
.then((resourceActionsData) => {
const machinesId = ObjectId();
const actionTest1 = ObjectId(resourceActionsData.find(x => x.name === 'test1')._id);
const actionTest2 = ObjectId(resourceActionsData.find(x => x.name === 'test2')._id);
const data = [
{
_id: machinesId,
name: 'machines',
actions: [
actionTest1,
actionTest2,
],
},
];
result = Resource.create(data);
if (result) SeedingHelper.saveData('resources', data);
});
return result;
}
}
module.exports = ResourcesSeeder;

Mongoose pagination from server side

I am trying to add server side pagination to a NodeJS, Express and MongoDB API. The API use mongoose to handle the database. I am lost in how to customize the response from the Controller.
Model:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const clientSchema = Schema({
code: {
type: String,
required: [true,'Code no puede estar vacio']
},
name: {
type: String,
required: [true,'Name no puede estar vacio']
}
},{
timestamps: true
});
const Client = module.exports = mongoose.model('clients',clientSchema);
Controller for get all clients:
const mongoose = require("mongoose");
const Client = require('../models/client');
const clientController = {};
clientController.index = (limit, callback) => {
Client.find(callback).limit(limit);
};
module.exports = clientController;
Route to get the clients:
app.get('/api/clients', (req, res) => {
Client.index(limit,(err, client) => {
if (err) {
res.status(500).json({
msg: "Error en aplicacion",
err
});
}
res.status(200).json(client);
});
});
How can I customize the result in the controller to something like this:
[
{
"totalRecords":"99999999999",
"offset":"888888",
"page":"4",
"nextPage":"5"
"result":{...}
}
]
I already have a function to calculate the pagination, But I don't know how to add the information about the pagination in the result of the controller.
Before I was adding the pagination data in the route, But I want to handle the pagination logic in the controller.
Or is better handle the pagination in the route?
Thanks in advance
You can create a method in mongoose model called as paginate :
Add this before declaring mongoose model :
clientSchema.methods.paginate = function(pageNo, callback){
var limit = 10;
var skip = pageNo * (limit - 1);
var totalCount;
//count documents
this.count({}, function(err, count)){
if(err){
totalCount = 0;
}
else{
totalCount = count;
}
}
if(totalCount == 0){
return callback('No Document in Database..', null);
}
//get paginated documents
this.find().skip(skip).limit(limit).exec(function(err, docs){
if(err){
return callback('Error Occured', null);
}
else if(!docs){
return callback('Docs Not Found', null);
}
else{
var result = {
"totalRecords" : totalCount,
"page": pageNo,
"nextPage": pageNo + 1,
"result": docs
};
return callback(null, result);
}
});
});
const Client = module.exports = mongoose.model('clients',clientSchema);
Then in controller change :
app.get('/api/clients', (req, res) => {
//You could put page number in request query ro request params
Client.paginate(req.body.pageNo, function(err, response) {
if (err) {
return res.status(500).json({
message : "Error en aplicacion",
error : err
});
}
return res.status(200).json(response);
});
});

How to save nested array in MongoDB using Mongoose and NodeJS

Can anyone explain me how to save the nested array items into mongodb with mongoose and nodejs?.
Here is a schema I am using.
var demoSchema = ({
"r_id": Number,
"r_label": String,
"entity": [{
"d_label": String,
"d_type": String
}
]
})
And here is Nodejs function I am using to save the data into db
app.route("/mypages/rooms")
.post(function(req, res) {
var db = mongoOp.demo();
var response = {};
req.checkBody("r_id", "Enter a valid r_id address.").notEmpty();
req.checkBody("r_label", "Enter a valid label address.").notEmpty();
var errors = req.validationErrors();
if (errors) {
console.log(errors);
console.log(req.body);
res.status(500);
res.end('500 Server Error');
//res.render('addrooms',{flag:1});
return;
} else {
db.r_id = req.body.r_id;
db.r_label = req.body.r_label;
db.entity = req.body.entity;
db.save(function(err) {
if (err) {
findfromdb(req, res, 2); //own function for implementation purpose
} else {
findfromdb(req, res, 1);
}
});
//var middleVar = req.body.resources;
// console.log(middleVar[0].d_rgb);
}
});
set entity with array []
db.entity = [{}];
app.route("/mypages/rooms")
.post(function(req, res) {
var db = mongoOp.demo();
var response = {};
req.checkBody("r_id", "Enter a valid r_id address.").notEmpty();
req.checkBody("r_label", "Enter a valid label address.").notEmpty();
var errors = req.validationErrors();
if (errors) {
console.log(errors);
console.log(req.body);
res.status(500);
res.end('500 Server Error');
//res.render('addrooms',{flag:1});
return;
} else {
db.r_id = req.body.r_id;
db.r_label = req.body.r_label;
db.entity = [{
"d_label": req.body.label_type,
"d_type": req.body.d_type
}];
db.save(function(err) {
if (err) {
findfromdb(req, res, 2); //own function for implementation purpose
} else {
findfromdb(req, res, 1);
}
});
//var middleVar = req.body.resources;
// console.log(middleVar[0].d_rgb);
}
});
The below operation adds the element label_type and d_type to entity array if they does not exist in the array, if they exists, then they won't be added
https://docs.mongodb.com/manual/reference/operator/update/addToSet/
Model.update(
query, // { _id: 1 }
{
$addToSet: {
"enity": {
"d_label": req.body.label_type,
"d_type": req.body.d_type
}
}
}
)
have a look at this answer
Pushing item to Mongodb collection array

How to query data from mongoDB with moongoose in nodejs

I only want to check if the key exist in the databse but when i try to query it I only get NULL.
This is my invite.js
var mongoose = require('mongoose');
mongoose.createConnection('mongodb://localhost/invitation');
var db2 = mongoose.createConnection;
// User Schema
var InvitationSchema = mongoose.Schema({
key: {
type: String,
index: true
},
used: {
type: String
}
});
var Invitation = module.exports = mongoose.model('Invitation', InvitationSchema);
module.exports.getUsedByKey = function(id, callback){
var query = {used: key};
Invitation.findById(query, callback);
};
module.exports.getInvitationByKey = function(key, callback){
var query = {key: key};
Invitation.findOne(query, callback);
console.log('keythingy ' + callback);
};
And this is how I try to use that function:
function checkKey(key, res) {
Invitation.getInvitationByKey(key, function(err, key2) {
//console.log('key: ' + key + '\nkey2: ' + key2.key)
if (err) throw err;
if (key2 !=null) {
return key2.key;
} else {
return false;
}
})
}
Use the below best way for write code in NodeJS. Mongoose.
Make one JavaScript class for connection with mongodb like --> db.js
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/invitation');
var Schema = mongoose.Schema;
// User Schema
var InvitationSchema = mongoose.Schema({
key: {
type: String,
index: true
},
used: {
type: String
}
}, {
collection: 'Invitation'
});
module.exports.Invitation = mongoose.model('Invitation', InvitationSchema);
Make another fetch data from collection JavaScript class --> invitation.js
var db = require('db.js');
module.exports.Initation = {
getInvitationByKey : function(key, callback) {
var query = {key: key};
db.Invitation.findOne(query, function(err, result){
console.log("Result : ", result, ", Error : ", err);
callback(err, result);
});
}
}
Make route JavaScript class --> invitation_route.js
var express = require('express');
var router = express.Router();
var invitation = require('invitation.js').Initation;
router.get('/get/:key', function(req, res, next) {
invitation.getInvitationByKey(req.params.key, function(err, result){
if (err) {
console.log(' Error : ', err);
res.body(err);
} else {
console.log(' Result : ' + JSON.stringify(result));
res.send(result);
};
});
});

Resources