NodeJs - Rendering same page after multiple SELECT queries - node.js

I have below codes in my index.js file. I can print data of profile table. And i need to print data of resume table also in same (index.njk) page. But i couldn't. I also found a similar question but i am new and couldn't modify those codes according to my project. Can you please help?
var express = require('express'),
path = require('path'),
bodyParser = require('body-parser'),
router = express.Router(),
app = express();
var pg =require('pg');
// DB Connect string
var connect = {
user: 'arslan',
database: 'resumedb',
password: '1984',
host: 'localhost',
port: 5432,
max: 10,
idleTimeoutMillis: 30000,
};
router.get('/', function(req, res){
pg.connect(connect, function(err, client, done, skills){
if(err){
return console.error('errrr', err)
}
//Get Profile Informations
client.query('select id,fname,lname,title,description,profileimage from profile', function(err, result){
if(err){
return console.error('error running query', err);
}
if(result.rows.length > 0) {
res.render('index.njk', {
profileName: result.rows[0].fname,
profileLName: result.rows[0].lname , profileTitle: result.rows[0].title
, profileDesc: result.rows[0].description
, profileImage: result.rows[0].profileimage
});
console.log(result.rows[0].profileimage);
}else {
console.log('No rows found in DB');
}
done()
});
});
});

The best solution for all async stuff is using Promises.
Your code uses the config for a connection pool, but later you dont use a pool, but its often a good idea to use one.
You create a new module db.js to query the db
const pg = require('pg')
const connect = { // Normaly you would use an config file to store this information
user: 'arslan',
database: 'resumedb',
password: '1984',
host: 'localhost',
port: 5432,
max: 10,
idleTimeoutMillis: 30000
}
let pool = new pg.Pool(config)
exports.query = (query, values) => {
return new Promise((resolve, reject) => {
pool.connect(function(err, client, done) {
if (err)
return reject(err)
client.query(query, values, (err, result) => {
done()
if (err)
return reject(err)
resolve(result)
})
})
})
}
exports.queryOne = (query, values) => {
return new Promise((resolve, reject) => {
this.query(query, values).then(rows => {
if (rows.length === 1) {
resolve(rows[0])
} else if (rows.length === 0) {
resolve()
} else {
reject(new Error('More than one row in queryOne'))
}
}).catch(err => {
reject(err)
})
})
}
pool.on('error', function (err, client) {
console.error('idle client error', err.message, err.stack)
})
and then in your route
// ...
const db = require('./db')
router.get('/', function(req, res, next) {
let profileQuery = db.queryOne('select id,fname,lname,title,description,profileimage from profile')
let resumeQuery = db.query('???')
Promise.all([profileQuery, resumeQuery]).then(([profile, resume]) => {
if (!profile) {
return res.status(404).send('Profile not found') // error page
res.render('index.njk', {
profileName: profile.fname,
profileLName: profile.lname,
profileTitle: profile.title,
profileDesc: profile.description,
profileImage: profile.profileimage
})
}).catch(err => {
next(err)
})
})
If you want to make a single query you can use db.query('select 1 + 1').then(rows => { /* your code */}).catch(err => { next(err) }).
Because you often only want one row you can use queryOne. It is returning undefined with no rows, the row you want, or an error for multiple rows
The next() with an error as argument will call the express error handlers. There you can log the error and return 500. You should create your own for that
Please ask if you dont understand something, because it could be complicated for the first time :)

Related

node-postgres returning undefined result

When i try to get result from node-postgres from my express app, pool.query is returning undefined result when i log it in console. Not sure if its about database connected properly or I am not returning the result properly? I am using heroku to deploy the app and using connection string given by heroku. Cant figure it out, anyone there to help please?.
db.js:
const { Pool } = require('pg');
const conString = process.env.DATABASE_URL;
const pool = new Pool({
connectionString: conString,
ssl: {rejectUnauthorized: false}
});
module.exports ={
getResult: (sql, params, callback)=>{
pool.query(sql, [params], (error, results)=>{
console.log(results);
if(!error){
callback(results);
}else{
callback(null);
}
pool.end();
});
}
}
user-model.js
var db = require('./db');
module.exports ={
findUserById: (userId)=>{
return new Promise((resolve, reject)=>{
var sql = "select id from users where id=?";
db.getResult(sql, [userId], (result)=>{
if(result.length>0){
resolve(true);
}else{
resolve(false);
}
});
});
}
}
seems the sent query parameter is in mysql format, use node-postgres format which is var sql = "select id from users where id = $1"; which should return valid result
It seems that your use of params is not correct.
You're passing an array to db.getResult(), then using it as the first element of another array.
Should just be pool.query(sql, params, (error, results)=>{ on that line.
you need to get the pool connection
const pool = require('./pool');
module.exports = {
// my version
findUserById(sql, params) {
return new Promise((resolve, reject) => {
return pool
.connect()
.then(conn => {
conn
.query(sql, [params])
.then(result => {
conn.release()
resolve(result)
})
.catch(error => {
conn.release()
reject(error)
})
})
})
},
// your version
findUserByIds: (userId) => {
return new Promise((resolve, reject) => {
var sql = "select id from users where id=?";
db.getResult(sql, [userId], (result) => {
if (result.length > 0) {
resolve(true);
} else {
resolve(false);
}
});
});
}
}
//// in you main or you controller file
// use the function
const { findUserById } = require('./model')
app.get('/user/:id', (req, res) => {
let sql = 'select * from "users" where "userId"= $1';
findUserById(sql, 1)
.then(result => {
res.status(200).send({
data: result
})
})
.catch(error => {
res.status(400).send(error)
})
})

How can I get list record from SQL Server in NodeJS

I start to develop a simple web application with NodeJS. and when I try to get a list record from SQL Server to show on the list page but somehow it's not working.
Here is the code :
const express = require("express");
const bodyParser = require("body-parser");
const sql = require("mssql");
const DBUtils = require("./DBUtils");
const app = express();
app.get("/all", (req, res, next) => {
let mypromise = new Promise((reso, rej) => {
let nameList = DBUtils.getNameList(sql);
if (nameList !== null || typeof nameList !== "undefined") {
reso(nameList);
} else {
rej("Error");
}
})
.then((result) => {
res.send(result);
})
.catch((err) => {
console.log(err);
});
});
app.get("/", (req, res, next) => {
console.log("the / route");
res.send("<h1>Hello to NodeJS</h1>");
});
app.listen(5003);
My DBUtils
const config = {
user: "sa",
password: "123",
server: "DESKTOP-7KGJI7L", // You can use 'localhost\\instance' to connect to named instance
database: "java",
options: {
encrypt: false,
},
};
const getNameList = (sql) => {
let nameList = "";
let errorString = "";
// Create connection
sql.connect(config, function (err) {
// Err
if (err) {
console.log(err);
}
// Create Request object
let sqlRequest = new sql.Request();
// QueryString
let queryString = `select * from NAME`;
// Run the query
sqlRequest.query(queryString, (err, data) => {
if (err) console.log(err);
//console.log(data); //data.recordset(array)[index].name
data.recordset.forEach((el) => {
nameList += `<li>${el.name}</li>`;
});
return nameList;
});
});
};
exports.getNameList = getNameList;
I pretty sure something wrong in Promise line but don't know how to fix it. Any suggest?
I think you are a newbie in Nodejs You made a common mistake. You did not use promise pattern correctly. Also, no need to pass next callback unless required.
Change getNameList as below :
const getNameList = (sql) => {
let nameList = "";
let errorString = "";
// Create connection
return new Promise (function(resolve,reject) {
sql.connect(config, function (err) {
// Err
if (err) {
console.log(err);
reject(err)
}
// Create Request object
let sqlRequest = new sql.Request();
// QueryString
let queryString = `select * from NAME`;
// Run the query
sqlRequest.query(queryString, (err, data) => {
if (err) {console.log(err)
reject(err)
}
//console.log(data); //data.recordset(array)[index].name
data.recordset.forEach((el) => {
nameList += `<li>${el.name}</li>`;
});
resolve(nameList);
});
});
})
};
Change app.get("/all") as below:
app.get("/all", (req, res) => {
DBUtils.getNameList(sql).then(function(list) {
res.status(200).send(list)
}).catch(function(err) { //handle error here
res.status(500)
})
})
Moreover, learn how to use promises and async-await.
Use appropriate body-parser as per requirement ie json, text etc.
Learn how and when to use next

Is there anything wrong with async/await in my code

Express API with mysql2
I want to use the async and await to query the data from the product table but nothing print at all, don't know how to use it properly.
exports.getAllTours = function(req, res) {
getTours()
.then(data => console.log(data))
.catch(err => console.log(err ));
}
async function getTours() {
var sql = "Select * from product_prd"
return new Promise(async function(resolve, reject) {
let [rows, fields] = await poolQuery(sql)
setTimeout(function() {
resolve(rows);
}, 500);
})
.catch(err => reject(err));
}
async function poolQuery(sql, args) {
return new Promise((resolve, reject) => {
promisePool.query(sql, args, (err, rows) => {
if (err)
return reject(err);
resolve(rows);
}).catch(err => reject(err));
});
}
I created the pool of connection like this by following the official documentation of mysql2
const mysql = require('mysql2');
const pool = mysql.createPool({
host: 'localhost',
user: 'super',
port: '3307',
password: 'sohail',
database: '784413_wonder',
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
});
// now get a Promise wrapped instance of that pool
const promisePool = pool.promise();
module.exports = promisePool;
I'm pretty sure there is a SQL error, and you cannot figure it out because the error handling in getTours is wrong.
Try this:
exports.getAllTours = function(req, res) {
getTours()
.then(data => console.log(data))
.catch(err => console.log(err ));
}
async function getTours() {
var sql = "Select * from product_prd"
return new Promise(async function (resolve, reject) {
let rows;
let fields;
try {
[rows, fields] = await promisePool.query(sql, args);
} catch (err) {
reject(err);
}
setTimeout(function () {
resolve(rows);
}, 500);
});
}

Node.js promises and call backs and asyncs

So I have done C++ Java and PHP and wanted to give a crack at Node.js. Below I have a very simple and unsecured SQL query.
module.exports = {
LoginCheck: function(data,cb){
console.log(data.password);
console.log(data.username);
if(data.username && data.password){
console.log('we have arrived');
var config = require(__dirname+'/../Config/config.json');
var mysql = require('mysql');
var con = mysql.createConnection({
host: config.LoginDBhost,
port: config.LoginDBport,
user: config.LoginDBusername,
password: config.LoginDBpassword,
database: config.LoginDB
});
con.connect(function(err) {
if (err) throw err;
console.log('we have connected');
con.query("SELECT * FROM `Users` WHERE `Username` = '"+data.username+"'", function (err, result) {
if (err) console.log(err);
if(result.Password){
if(result[0].Password){
if(result[0].Password == data.password){
console.log('true');
cb(true);
}
}
}
});
});
}
//either password is null or didnt match on file... if we are this far its a fail
console.log('false');
cb(false);
},
bar: function () {
// whateverss
}
};
The code does not wait for the sql connection and skips to being false. I been banging my head on a desk for days trying to figure out how promises and callbacks works after years of having my code follow steps layed.
Could someone convert this and explain how to force my code to be synchronous when I need it to be?
Try this code :
module.exports = {
LoginCheck: function(data,cb){
console.log(data.password);
console.log(data.username);
if(data.username && data.password){
console.log('we have arrived');
var config = require(__dirname+'/../Config/config.json');
var mysql = require('mysql');
var con = mysql.createConnection({
host: config.LoginDBhost,
port: config.LoginDBport,
user: config.LoginDBusername,
password: config.LoginDBpassword,
database: config.LoginDB
});
con.connect(function(err) {
// I think cb(false) here but you use throw err.
if (err) throw err;
console.log('we have connected');
con.query("SELECT * FROM `Users` WHERE `Username` = '"+data.username+"'", function (err, result) {
if (err) console.log(err);
if(result.Password){
if(result[0].Password){
if(result[0].Password == data.password){
console.log('true');
cb(true);
}
}
}
//either password is null or didn't match on file... if we are this far its a fail
console.log('false');
cb(false);
});
});
}
},
bar: function () {
// whateverss
}
};

Botpress - how to bring database values into the chat window?

I'm trying to build a chatbot using Botpress. I'm a beginner, looking for your help. One of the requirements is to query database to answer questions. This is what I have tried so far:
dbconnect.js
var oracledb = require('oracledb');
var dbConfig = require('./dbconfig.js');
var db = function dbCall(sql, values) {
return new Promise(function(resolve, reject){
oracledb.getConnection(
{
user : dbConfig.user,
password : dbConfig.password,
connectString : dbConfig.connectString
},
function(err, connection) {
if (err) {
reject(err);
return;
}
connection.execute(
sql,
values,
{
maxRows: 1
},
function(err, result) {
if (err) {
console.error(err.message);
return;
}
resolve(result);
doRelease(connection);
}
);
});
});
}
// Note: connections should always be released when not needed
function doRelease(connection) {
connection.close(
function (err) {
if (err) {
console.error(err.message);
}
});
}
module.exports = db;
select.js
var dbConnect = require('../oracledb/dbconnect');
dbConnect('select code from table1' +
' where id=:id', {id:'value1'}).then(function (response) {
console.info(response.rows);
}).catch(function(error) {
console.info(error);
});
everything above works great, if I run select.js. How could I bring the response into the botpress chat window? I tried placing the select.js code in index.js event.reply, it doesn't work.
Thanks,
Babu.
I have resolved this by using the promise directly in the action.
return dbConnect('<SQL here>=:id', { id: Id })
.then(function(response) {
var res = response.rows
console.info(res);
const newState = { ...state, status: res}
return newState
})
.catch(function(error) {
console.info(error)
})
Note that response has the resultset.

Resources