Mongoose Collections List Method - node.js

Im new about the Mongoose. So I'm trying to do collections table.
I've this type of Schema for operators:
const operatorSchema = new Schema({
operatorName: {
type: String
},
productsSerialNumber:[{productSerialNumbers: String}],
operatorSerialNumber: {
type: Number
},
users:[{
email:String,
payment:Number,
paymentsData: Date,
}],
operatorState:{
type: Boolean,
}
});
I want to create table like this,
users using some products and I want to list which user using this product also where and when.
As below lines:
OperatorName|productsSerialNumber|username|mail|Date|Payment
But in nodejs side, I couldnt success because users is an Array and how can I get every line from database.
I'm trying like this:
const operatorArray = []
const userArray = []
exports.getOperatorInformations = (req, res, next)=>{
Operators.find({},function(err,docs){
docs.forEach(function(dataCatch){
console.log(dataCatch)
operatorArray.push(dataCatch)
res.render('home',{operators: operatorArray });
})
})
}
}
operatorArray includes all informations, so I send to ejs side:
<% operators.forEach(function(data,index){ %>
<%console.log(index)%>
<tr>
<td>
<%= data.operatorName %>
</td>
<td>
<%= data.productsSerialNumber %>
</td>
<td>
<%= data.productsSerialNumber %>
</td>
<td>
<%= data.users[index].email %>
</td>
<td>
<%= data.users[index].paymentsData %>
</td>
<td>
<!-- <%= data.users[index].payment %> -->
</td>
</tr>
<% })%>
index return length of the operators object. But I want to see lenght of user, when I try with operators.users.forEach It doesnt work. How can I do this ?

You could return the docs array directly to the ejs:
exports.getOperatorInformations = (req, res, next) => {
Operators.find({}, function (err, docs) {
if (err) console.log(err)
else res.render('home', { operators: docs });
});
};
And change your ejs to:
<% operators.forEach(function(data){ %>
<% data.users.forEach(function(user){ %>
<tr>
<td><%= data.operatorName %></td>
<td><%= data.productsSerialNumber %></td>
<td><%= data.productsSerialNumber %></td>
<td><%= user.email %></td>
<td><%= user.paymentsData %></td>
<td><!-- <%= user.payment %> --></td>
</tr>
<% })%>
<% })%>

Related

How to set active tab dynamically in ejs templates of nodejs express app?

This is my header template, which will load to every page.
<!-- ======= Header ======= -->
<header id="header" class="d-flex align-items-center">
<div class="container d-flex align-items-center justify-content-between">
<h1 class="logo"><%= title %><span>.</span></h1>
<!-- Uncomment below if you prefer to use an image logo -->
<!-- <img src="/assets/img/logo.png" alt="">-->
<nav id="navbar" class="navbar">
<ul>
<%
const menu = [
{
name: 'Home',
url: '/'
},
{
name: 'About',
url: '/about'
},
{
name: 'Services',
url: '/services'
},
{
name: 'Portfolio',
url: '/portfolio'
},
{
name: 'Team',
url: '/team'
},
{
name: 'RatesCalculator',
url: '/ratesCalculator'
},
{
name: 'Contact',
url: '/contact'
}
]
for ( let i in menu ) { %>
<% if ( menu[i].name.toLowerCase() == activestate.toLowerCase() ) { %>
<li><a class="nav-link scrollto active" href="<%= menu[i].url %>" ><%= menu[i].name %></a></li>
<% } else { %>
<li><a class="nav-link scrollto" href="<%= menu[i].url %>" ><%= menu[i].name %></a></li>
<% } %>
<% } %>
</ul>
<i class="bi bi-list mobile-nav-toggle"></i>
</nav><!-- .navbar -->
</div>
</header><!-- End Header -->
To set it dynamically, the active tab, I am using the logic below in template and the middleware in index.js.
app.use(function(req, res, next){
console.log(req)
res.locals.title = "Marker";//To set website title
req.active = req.path.split('/')[1] // [0] will be empty since routes start with '/'
if (req.length === 0) req.active = "Home"
next();
});
It is working but I feel it is bit complicated and repetitive code is there.
Can you please suggest a better approach.

Search array MongoDB NodeJS

I am struggling to get records where the name matches the name i have stored an another database.
I can retrieve all fields of data but i am struggling to get specific records i.e. where name = either jack or jill.
I want to use a variable i take from my passport log in which i can access at req.user.username.
I tried using findOne and manipulating the ejs array without any luck.
It prints to the console but i cannot display on vieworders.ejs
I think i am overcomplicating, what is the best way to find and display records where applicationDB.name = req.user.username?
server.js is
app.get('/vieworders', require('connect-ensure-login').ensureLoggedIn(), function(req, res) {
Myapplication.find(function(err, myorders) {
res.render('vieworders', { user: req.user, myorders: myorders});
console.log(myorders);
});
});
vieworders.ejs is
<h1> Display Orders Here </h1>
<% if(myorders.length>0) { %>
<table border="1">
<tr>
<th>Index</th>
<th>Name</th>
<th>size</th>
</tr>
<% for(var i=0; i<hurleys.length;i++) { %>
<tr>
<td><%= i %></td>
<td><%= myorders[i].name %></td>
<td><%= myorders[i].orderssize %></td>
</tr>
<% } %>
</table>
<% } else { %>
No Record Found
<% } %>
MyApplication schema is
const mySchema= new Schema({
name: {
type: String,
required: true,
},
ordersize: {
type: String,
required: true,
},
});
module.exports = mongoose.model('MyApplication', mySchema);
You have to pass the query filter as the first parameter of the find method.
This should do the trick, assuming the username is stored in the Schema as name.
app.get('/vieworders', require('connect-ensure-login').ensureLoggedIn(), function(req, res) {
Myapplication.find({name: req.user.username}, function(err, myorders) {
res.render('vieworders', { user: req.user, myorders: myorders});
console.log(myorders);
});
});

how to associate data schema in mongoose

I'm trying to associate 2 schema on nodejs/mongoose app.
my first model:
var mongoose = require("mongoose");
var projectSchema = new Schema({
pname: String,
pnumber: String,
plocation: String,
pclient: String,
clientabn: String,
contname: String,
contnumber: String,
mobile: String,
address: String,
city: String,
country: String,
boqs: [{
type: mongoose.Schema.Types.ObjectId,
ref: "Boq",
}]
});
module.exports = mongoose.model("Project", projectSchema);
second model:
var mongoose = require("mongoose");
var boqSchema = new Schema({
boqDesc: String,
boqUnit: String,
boqQty: String,
boqRate: String,
boqPrice: String,
});
module.exports = mongoose.model("Boq", boqSchema);
And this is my post rout:
app.post("/myprojects/:id/boq", function(req, res) {
Project.findById(req.params.id, function(err, project) {
if (err) {
console.log(err);
} else {
Boq.create(req.body.boq, function(err, boq) {
if (err) {
console.log(err);
} else {
project.boqs.push(boq);
project.save();
res.redirect("/myprojects/" + project._id + "/boq");
console.log(boq);
}
});
}
});
});
When is posting, only an id of boq will be saved on database not any data from boq's form. anyone knows what is wrong with this code?
output of console.log:
console.log output
console.log(project)
Below is the post form:
<form action="/myprojects/<%= project._id %>/boq" method="POST">
<table class="table" id="toptab">
<tbody>
<tr>
<td class="td6"><b>No.</b></td>
<td class="td7"><b>Item Description/Scope of Work</b></td>
<td class="td8"><b>Unit</b></td>
<td class="td9"><b>Quantity</b></td>
<td class="td10"><b>Rate</b></td>
<td class="td11"><b>Price</b></td>
</tr>
<tr>
<td class="td6"></td>
<td class="td7" contenteditable="true" name="boq[boqDesc]"></td>
<td class="td8" contenteditable="true" name="boq[boqUnit]"></td>
<td class="td9" contenteditable="true" name="boq[boqQty]"></td>
<td class="td10" contenteditable="true" name="boq[boqRate]">$</td>
<td class="td11" contenteditable="true" name="boq[boqPrice]"></td>
</tr>
</tbody>
</table>
<button type="submit" name="submit" class="btn btn-primary">Save</button>
</form>
you're calling Boq.create(undefined, callback);
this creates a boq document in db with no fields (except the _id).
it passes validation because all boq's fields are not required.
go to your client, and make sure you're adding boq data to http request's body correctly.
add <input> elements in between <td></td> tags, each named after one of the fields in boq's schema. for instance <td><input type="text" name="boqDesc"></td>

Passing sub document to view

in my schema where i have company with sub document PostedJobs of type array
all companies of are passed to user view
Get Company
router.get('/', isLoggedIn , function(req, res, next) {
Company.find({'Creator': req.user.id}).then(function(companies) {
res.render('Company', { "Companies" : companies });
});
});
after getting a specific company i get that company by name which is unique
router.get('/:name' , isLoggedIn , function(req , res , next) {
var name = req.params.name;
Company.findOne({Name : name}).then(function(Company) {
res.render('dashboard',{
"Company" : Company
});
});
});
with this view i want to also pass PostedJob into company view
The Sub document is present in page and you can access it as i access it as following
<% Company.PostedJobs.forEach(function(Job ,index){%>
<tr>
<td><%= index+1 %></td>
<td><%=Job.JobName %></td>
<td><%=Job.JobType %></td>
<td><%=Job.JobLocation %></td>
<td><%=Job.JobSalary %></td>
</tr>
<%}) %>

How to use route parameters with Express

I'm having difficulty connecting the dots with the router.params objects with express.
Right now I'd like to have the button-success button in the code below point to a url that reads someaddress.com/formula/:item._id
HTML: (EJS Templating Engine)
<% formulas.forEach(function(item){ %>
<div class="pure-u-1 pure-u-sm-1-2 pure-u-md-1-4 pure-u-xl-1-5">
<div class="formula-block centered" id="<%= item._id %>">
<h4 class="padded-top"> <%= item.name %></h4>
<p> <%= item.description %></p>
<button class="button-success pure-button">Show</button>
<button class="button-warning pure-button">Delete</button>
</div>
</div>
<% }); %>
I am pairing that with this Express route:
router.get('/formula/:id', function(req, res){
var db = req.db;
var collection = db.get('formulas');
var id = req.params.id;
collection.find({"_id": id}, {}, function(e, doc){
res.render('formula/:id', {
formula: doc,
title: `formula for ${doc.name}`,
description: `modify and view ${doc.name} formula`
});
});
});
which then uses the information from the MongoDB document to generate the page.
It's not clear to me how you do this from looking at the documentation.
Thank you for your help.

Resources