How do I tailor my query to get a specific title? - node.js

I have a query in my app.js file that renders into my list page list.ejs found at http://localhost:4100/list. As the name may suggest, the list page displays a list of ALL the transactions stored in the database, though I would be more interested in only displaying all the transactions strictly within the county of Nairobi.
Find below the contents of my app.js file:
app.get('/list', (req,res)=> {
let countyName;
countyName = transModel.findOne({ transCounty : /Nairobi/i, })
.limit(5)
.select({ transCounty:1})
.exec( (err, result)=> {
if (err) throw err;
console.log('>> ' +result);
return result;
});
console.log ('countyName: ' +countyName);
transModel.find( (err, docs)=> {
if (!err)
{
res.render('list', {data : docs, countyName: countyName});
}
else
{
// res.status(status).send(body);
}
})
});
In the terminal, the code above yeilds:
countyName: undefined
>> { _id: 609f7ed8fe1fd8b3193b0b77, transCounty: 'Nairobi' }
My list.ejs looks like this:
<h1> Transactions </h1>
<p>
Name of County: <%= countyName %>
</p>
<table>
<tr>
<th> _id </th>
<th> Transaction Amount </th>
<th> Transaction County </th>
<th> Transaction Industry </th>
</tr>
<% data.forEach(function(entry) {%>
<tr>
<td> <%=entry._id%> </td>
<td> <%=entry.transAmount%> </td>
<td> <%=entry.transCounty%> </td>
<td> <%=entry.transIndustry%> </td>
</tr>
<%});%>
</table>
The above list.ejs file, though correctly renders a table with the desired content from the database isn't able to pick the name of the County. Kindly help me figure out how I can achieve this.
Find below an image of the rendered list.ejs:
Kindly note Name of county is undefined.
How do I formulate my query be able to yield all transactions within only Nairobi, and also display the name of the county in the ejs file.
Looking forward to your help.

You should wait for the promise to resolve before using its value:
countyName = await transModel.findOne({
transCounty: /Nairobi/i,
})
.limit(5)
.select({
transCounty: 1
})
.exec();

Related

handlebars.js build in helper #each not working

I am using expressjs and mongoose in backend and handlebars as view engine.
Here is my method in index js
const router = require('express').Router()
const Product = require('../../models/Products')
// Products
router.get('/products',async (req, res) => {
try{
const products = await Product.find()
res.status(200).render('products',{products})
}catch(err){
res.status(400).render('products')
}
})
Documents inside product collection is like this:
[
{
_id: new ObjectId("632d74a0b828b58a1d25b047"),
title: 'Footballs',
description: 'This is a nice product.',
images: [
'/product-images/1663923360491/image1.png',
'/product-images/1663923360491/image2.png'
],
categories: [ 'football', 'balls', 'sports' ],
price: 800,
stock: 300,
createdAt: 2022-09-23T08:56:00.546Z,
updatedAt: 2022-09-23T08:56:00.546Z,
__v: 0
}
]
And here is the foreach sentence at index.hbs
<table>
<thead>
<tr>
<td>Date</td>
<td>Product</td>
<td>Price</td>
<td>Options</td>
</tr>
</thead>
<tbody>
{{#each products}}
<tr>
<td>{{this.createdAt}}</td>
<td>{{this.title}}</td>
<td>₹{{this.price}}</td>
<td>
<button>edit</button>
<button>delete</button>
</td>
</tr>
{{/each}}
</tbody>
</table>
This code is not working (td tag is empty). But when I put {{#index}},the index of the current array item is displaying but other values are not displaying.
{{#each products}}
<tr>
<td>{{#index}}</td>
<td>{{this.title}}</td>
<td>₹{{this.price}}</td>
<td>
<button>edit</button>
<button>delete</button>
</td>
</tr>
{{/each}}
Any help is greatly appreciated, thanks in advance!
You don't need to use this here:
{{#each products}}
<tr>
<td>{{createdAt}}</td>
<td>{{title}}</td>
<td>₹{{price}}</td>
<td>
<button>edit</button>
<button>delete</button>
</td>
</tr>
{{/each}}
If using mongoose, this issue can be solved by using .lean() to get a json object (instead of a mongoose one):
const products = await Product.find().lean()
res.status(200).render('products',{products})

How to format the date with month/day/year from Sun May 04 1980 00:00:00 GMT+0500 (Pakistan Standard Time) in nodejs javascript mysql

This is the code of the main page like in the screenshot. Using mysql to get that data, it is a CRUD application with nodejs, express, mysql and bootstrap. Don't know how to format the date to (month/day/year) instead of (Sun May 04 1980 00:00:00 GMT+0500 (Pakistan Standard Time)). Please help. New to javascript programming, so i am struggling :(
<div class="row">
<div class="col-6"><h1>Users</h1></div>
<div class="col-6 d-flex justify-content-end">
+ add new user
</div>
</div>
<table class="table table-bordered">
<thead class="thead-dark">
<tr>
<th scope="col">#</th>
<th scope="col">First Name</th>
<th scope="col">Last Name</th>
<th scope="col">DoB</th>
<th scope="col">Phone</th>
<th scope="col" class="text-end">Action</th>
</tr>
</thead>
<tbody>
{{#each rows}}
<tr>
<th scope="row">{{this.id}}</th>
<td>{{this.first_name}}</td>
<td>{{this.last_name}}</td>
<td>{{this.dob}}</td>
<td>{{this.phone}}</td>
<td class="text-end">
<i class="bi bi-eye"></i> View
<i class="bi bi-pencil-square"></i> Edit
<i class="bi bi-person-x"></i> Delete
</td>
</tr>
{{/each}}
</tbody>
</table>
// View users
exports.view = (req, res) => {
pool.getConnection((err, connection) =>{
if(err) throw err; // not connected
console.log('DB connected as ID' + connection.threadId);
// User the connection
connection.query('SELECT * FROM users ', (err, rows)=> {
// When done with the connection, release it
connection.release();
if(!err){
let removedUser = req.query.removed;
res.render('home', { rows, removedUser });
}
else {
console.log(err);
}
console.log('The data from user table: \n', rows);
});
});
}
You can update the Date format in your SQL query while fetching values. Simply mention the required date format and pass the value to your view engine.
connection.query('SELECT all_required_columns, DATE_FORMAT(dob, "%m/%d/%y") as dob FROM users ', (err, rows)=> {
This should fetch all values from the DB with DOB format as mm/dd/yy.
PS: The North Remembers

Map array dont show in table

I need map a array inside my page, and show the result in a table, but the content don't show up when I compiled the page.
Can anyone help me?
When I print in console the content of a var, this is here. But the info don't show up in the page
import Layout, { siteTitle } from '../components/layout'
const fetch = require('node-fetch');
export default function Home({ devices }) {
return (
<Layout >
{devices.map((device) => (
<table>
<thead>
<th>
{device.localname} / {device.localIP}
</th>
</thead>
{console.log('1')}
<tbody>
<tr>
<td>
{device.IPaddress[0][3].value} // I put this to test, and this works fine
</td>
</tr>
{device.IPaddress.map((port) =>{
<tr>
<td>
{console.log(port[3].value), port[3].value} // here I need to work, I want to put all results of port in a TD tag, the console.log shows up the info, but the page not.
</td>
</tr>
})}
</tbody>
</table>
))}
</Layout >
)
}
export async function getStaticProps() {
const res = await fetch('http://localhost:3000')
const devices = await res.json()
return {
props: {
devices
}
}
}
As commented by #evgenifotia, change the ( for { inside the second array map works fine.
here the final function:
export default function Home({ devices }) {
return (
<Layout >
{devices.map((device) => (
<table>
{console.log('1')}
<tbody>
<tr>
<th>
{device.localname} / {device.localIP}
</th>
</tr>
{device.IPaddress.map(port =>(
<tr>
<td>
{console.log(port[3].value), port[3].value}
</td>
</tr>
))}
</tbody>
</table>
))}
</Layout >
)
}

How to render sqlite3 data into HTML tables using {{#each}}

I am following a node.js tutorial but instead of using mongodb I am trying out sqlite. I have everything working. I am able to store data into the sqlite database but now I need to display it in an HTML table. Here's my code for retrieving data from a table called News
index: (req,res) => {
let sql = 'SELECT *'
sql += 'FROM News'
db.all(sql, [], (error, rows) => {
if (error){
console.log(error);
}
res.send(rows);
//res.redirect('admin/index');
});
},
Now I am able to send this row to the browser using
res.send(rows)
Here is my html code,
<div class="container-fluid">
<div class="alert alert-secondary text-center">
<h1>ALL POSTS</h1>
</div>
<table class="table table-bordered">
<thead class="bg-dark text-center">
<tr class="text-white">
<th>ID</th>
<th>Title</th>
<th>Content</th>
</tr>
</thead>
<tbody class="text-center">
{{#each this}}
<tr>
<td>{{id}}</td>
<td>{{title}}</td>
<td>{{content}}</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
I tried to use res.render after res.send to render the tables but it throw error
Cannot set headers after they are sent to client.
How do I do this solve this? I can see the data in my browser now I want to render it in my table.
Hi guys I figured it out. You have to render the page and send data in the same res.render(). So this is what you have to do,
//just remove the
res.send(rows);
//and replace it with
res.render('admin/index', {news:rows});
and replace with in your html/handlebars
{{#each news}}

How to use search filter in Angular for nested JSON object?

I am bringing data from my mongoose to display on my HTML table. I am able to filter a JSON object normally but unable to filter nested JSON object?
I have used "npm i ng2-search-filter --save " to import filter pipe, but this only works for the first level. Doesn't do filter for the nested JSON object.
My JSON object is:
{
packageName:test,
packagePrice:200,
userid:{
userName:John,
userAge: 27
}
}
<input type="text" class="form-control" [(ngModel)]="searchtext"
placeholder="Search">
<table class="table table-hover">
<thead>
<tr>
<th scope="col">Package Name</th>
<th scope="col">Package Price</th>
<th scope="col">Customer Name</th>
<th scope="col">Customer Age</th>
</tr>
</thead>
<tbody *ngFor="let use of user | filter:searchtext">
<tr class="table-active">
<td> {{use.packageName}}</td>
<td>{{use.packagePrice}}</td>
<td>{{use.userid.userName}}</td>
<td>{{use.userid.userAge}}</td>
</tr>
</tbody>
</table>
When I enter packageName and packagPrice in a textbox for search filter it filters out and shows me correct result, but on userName and userAge its not working.
Please help.
Thank you.
I solved this with by just installing the latest version ng2 search filter.
Run below command:
npm i ng2-search-filter#0.5.1
You can use custom search pipe for this
I have create demo on Stackblitz
searchPipe.ts
transform(value: any, searchText?: any): any {
if(!value) return [];
if(!searchText) return value;
searchText = searchText.toLowerCase();
return value.filter( it => {
return it.packageName.toLowerCase().includes(searchText) || it.packagePrice.toString().includes(searchText) || (it.userid && it.userid.userAge.toString().includes(searchText) || it.userid.userName.toLowerCase().includes(searchText));
});
}
component.html
<tr class="table-active" *ngFor="let use of user | search:searchtext">
<td> {{use.packageName}}</td>
<td>{{use.packagePrice}}</td>
<td>{{use.userid.userName}}</td>
<td>{{use.userid.userAge}}</td>
</tr>
Try the below:-
function getResult(filterBy, objList) {
return objList.hightlights.filter(function(obj) {
return obj.queries.some(function(item){
return item.indexOf(filterBy) >= 0;
});
});
}

Resources