node-postgres returning undefined result - node.js

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)
})
})

Related

Is it possible to export data from .then function?

I am working with Node and MSSQL Server using the mssql module. When consuming a promise, I would like to export or return data from the .then function. Is this possible or are there any workarounds?
getDb = function(){
// This code establishes connection to SQL Server
const conn = new sql.ConnectionPool(dbConfig);
const req = new sql.Request(conn)
conn.connect()
.then(function getData (req) {
// This code makes query to SQL Server
req.query("SELECT * FROM USER")
.then(function(res){
console.log(res) // logs Correct User
module.exports.user = res // logs undefined in main.js
})
.catch((err) => console.log(err))
}
)
.catch(function (err) {
console.log(err);
});
}
getDb()
Any help is greatly appreciated!
Here is a simple way you can export the getDb function and import and consume it to the the data:
exports.getDb = () => {
return new Promise((resolve, reject) => {
const conn = new sql.ConnectionPool(dbConfig);
const req = new sql.Request(conn)
conn.connect().then(req => {
return req.query("SELECT * FROM USER")
}).then(res => {
return resolve(res);
}).catch(err => {
console.log(err)
})
})
}

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

Nested queries, promises on nodejs

Im trying to build a rest api, fetching a nested mysql queries.
When i fetch the first query, this return a array, then with this array i need to fetch data with another query for each value through a array.map
when the script running, always log a empty array, i think must be cause of promises. any help please?
//this the mysql queries
const getTournaments = 'SELECT ID FROM wp_posts WHERE post_type = "tournament"'
const getTournamentGame = 'SELECT meta_value FROM wp_postmeta WHERE meta_key = "tournament_game" AND post_id = ?'
async function fetchType(id){
return new Promise ((res, rej) => {
try{
pool.query(getTournamentGame, [id], (err, rows) => {
if (err) {
return rej(err)
}else {
return res(rows[0].meta_value)
}
})
} catch(err){
console.log(err)
}
})
}
async function mapeado(array) {
return new Promise (async (resolve,rej) => {
try{
var arr = []
array.map((item) => {
fetchType(item.ID).then((res) => {
var tourData = {
id: item.ID,
type: res
}
return tourData
}).then((data) => {
arr.push(data)
})
})
return resolve(arr)
} catch(err) {
console.log(err)
}
})
}
//making rest api
app.get('/tournaments', async (req, res) => {
pool.query(getTournaments, (err, rows) => {
mapeado(rows).then(console.log)
})
})

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);
});
}

NodeJs - Rendering same page after multiple SELECT queries

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 :)

Resources