Node JS infinite wait - javascript

I'm developing a simple program that fetches data from a database. But when connected, infinite loading occurs.
router
router.get('/', (req, res) => {
res.render('/music', '', musicController.getMusicList)
})
controller
'getMusicList' : async () => {
try {
var music_list = await musicModel.getMusicList()
return music_list
} catch (e) {
console.log(e)
}
}
model
'getMusicList' : (req, res) => {
return new Promise( async (resolve, reject) => {
try {
await dbcon.query("SELECT * FROM music", (error, results) => {
console.log(error)
if (error) {
reject(error)
} else {
resolve(results)
}
})
} catch (e) {
reject(e)
}
})
}

i solved my self
i changed my router source code
router.get('/', async (req, res) => {
let list = await musicController.getMusicList()
res.render('/index', {list : list})
})

Related

Getting PostgresSQL 42703 error (invalid column error)

I am working on a React project with PostgreSQL database, this is the first time I am using it, and I am getting 42703 error on querying a particular column.
Below is the code I have written to query
const getList = (userId) => {
return new Promise(function (resolve, reject) {
pool.query(`SELECT items FROM public."user" where id=${userId}`, (error, results) => {
if (error) {
reject(error)
}
resolve(results);
})
})
}
I have defined this getList function and then I am making an api call to call this function by passing the userId like this
app.get(`/expenses`, verifySession(), async (req, res) => {
const userId = req.session.userId;
database.getList(userId)
.then(response => {
res.status(200).send(response);
})
.catch(error => {
res.status(500).send(error);
})
})
I even tried passing the userId directly as shown below , still it gives me the same error , which probably means I am querying in a wrong way
app.get(`/expenses`, verifySession(), async (req, res) => {
//const userId = req.session.userId;
database.getList('17a6dea6-a63e-4da7-9910-df7eddb672e6')
.then(response => {
res.status(200).send(response);
})
.catch(error => {
res.status(500).send(error);
})
})
Only when I directly write the string in the query it works properly like this
const getList = (userId) => {
return new Promise(function (resolve, reject) {
pool.query(`SELECT items FROM public."user" where id='17a6dea6-a63e-4da7-9910-df7eddb672e6'`, (error, results) => {
if (error) {
reject(error)
}
resolve(results);
})
})
}
Can someone please help we with what is exactly going wrong and if my syntax is correct or not ?
This is the frontend part of where I am calling the api.
function getDataForUser() {
fetch(`http://localhost:3001/data`)
.then(response => {
return response.json();
}).then(data => {
console.log(data.rows[0]);
})
}
This problem happened because you didn't use a single quotation for string type in the query. When using where id=${userId} and called with 17a6dea6-a63e-4da7-9910-df7eddb672e6 converted to where id=17a6dea6-a63e-4da7-9910-df7eddb672e6 and this make problem.
You can use two scenarios to handle it:
Use the single quotation for string type:
const getList = (userId) => {
return new Promise(function (resolve, reject) {
pool.query(`SELECT items FROM public."user" where id='${userId}'`, (error, results) => {
if (error) {
reject(error)
}
resolve(results);
})
})
}
Use parameter binding (As default it converted type)
const getList = (userId) => {
return new Promise(function (resolve, reject) {
pool.query(`SELECT items FROM public."user" where id=$1`, [userId], (error, results) => {
if (error) {
reject(error)
}
resolve(results);
})
})
}

How to console reject resolve message in postman using node js

How can be resolve executed in multiple function.
As I have multiple promise function and each function contain resolve message but don't how to print this on postman
If there is single function with promise then resolve message easily get executed but what if there is function of function then how can it be possible ?
Is this possible way to return resolve or reject message from one function to another?
As I am writing to pass resolve message in postman whenever my task is completed or reject message when there is some error
But after after writing return it still not returning the resolve message or reject message inside Postman
any idea how this can be resolve?
async function readFile(filePath) {}
async function getAllFile(filePath) {
const paths = await readFile(filePath);
}
async function filterFiles(filePath) {
const paths = await getAllFile(filePath);
}
function addDocument(data){
return new Promise((resolve, reject) => {
Document.create({
name: data.name,
},
}).then(function (filePath) {
filterFiles(filePath);
let msg = "Document created Succesfully";
return resolve(msg);
})
.catch(function (err) {
return reject("Can't be updated please try again :) " + err);
});
});
}
function updateDoc(data){
return new Promise((resolve, reject) => {
Document.update({
name: data.name,
}
where: {
product_id: data,
},
})
}).then(function (filePath) {
getAllFile(filePath);
let msg = "Updated Successfully";
return resolve(msg);
})
.catch(function (err) {
return reject("Can't be updated please try again :) " + err);
});
}
function findDoc(data){
return new Promise((resolve, reject) => {
Document.findAll(
{
raw:true,
},
{
name: data.name,
}
where: {
product_id: data,
},
})
}).then(function (product) {
if(product.length===0){
addDocument(product);
let msg="task completed";
return resolve(msg,product);
else{
return resolve(updateDoc(product));
}
})
.catch(function (err) {
return reject("Can't be updated please try again :) " + err);
});
}
function findDoc(data){
return new Promise((resolve, reject) => {
Document.findAll(
where: {
product_id: data.id,
},
})
}).then(function (product) {
findDoc(product);
let msg="task completed";
return resolve(msg,product);
})
.catch(function (err) {
return reject("Can't be updated please try again :) " + err);
});
}
How can i get resolve message in postman
It's hard for me to test your codes but it's quite possible to return resolve, reject messages in the response object.
If you want to pass a reject message through 3 promise for example and return a response you need use try, catch blocks, you can check this example:
// index.js
const express = require('express')
const app = express()
const port = 3000
const responder1 = (error, message) => {
return new Promise((resolve, reject) => {
if (error) {
reject(error);
return;
}
resolve(message);
});
};
const responder2 = (error, message) => {
return new Promise((resolve, reject) => {
if (error) {
reject(error);
return;
}
resolve(message);
});
};
const responder3 = (error, message) => {
return new Promise((resolve, reject) => {
if (error) {
reject(error);
return;
}
resolve(message);
});
};
app.use('/', async (req, res) => {
let result;
try {
const error = new Error("This is a error message.");
result = await responder1(error, null);
} catch (error1) {
try {
await responder2(error1, null);
} catch (error2) {
try {
await responder3(error2, null)
} catch (error3) {
res.send({
success: 0,
message: error3.message
});
return;
}
}
}
res.send({
success: 0,
message: result
});
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
And if you want to pass resolve message:
const express = require('express')
const app = express()
const port = 3000
const responder1 = (error, message) => {
return new Promise((resolve, reject) => {
if (error) {
reject(error);
return;
}
resolve(message);
});
};
const responder2 = (error, message) => {
return new Promise((resolve, reject) => {
if (error) {
reject(error);
return;
}
resolve(message);
});
};
const responder3 = (error, message) => {
return new Promise((resolve, reject) => {
if (error) {
reject(error);
return;
}
resolve(message);
});
};
app.use('/', async (req, res) => {
let result = await responder3(null, await responder2(null, await responder1(null, "This is a test message.")));
res.send({
success: 0,
message: result
});
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})

I want to show all my tables from my database to an API

I have 3 tables (services, practitioners, network) in my postgres database and I want them all to show in my API, but I got this error
(node:21300) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
and this is the only output I could get
json response
here is my code.
const handler = (req, res, db, tableName) => {
try{
db.select('*').from(tableName)
.then(data => {
if(data.length){
res.status(200).json({tableName: data});
}
})
}catch(err){
res.status(400).json(err)
}
}
const content = (req, res, db) => {
handler(req, res, db, 'services')
handler(req, res, db, 'practitioners')
}
module.exports = { content };
edit:
here's what I did from Nabil Farhan's answer, and it's working just what I wanted. screenCapture
const getData = async (db, tableName) => {
return new Promise((resolve, reject) => {
db.select('*').from(tableName)
.then(data => {
resolve({[tableName]:data})
})
});
}
const contentHandler = async (req, res, db) => {
// get the argument from get request
let allTable = [];
const table_a = await getData(db, 'services');
const table_b = await getData(db, 'practitioners');
allTable.push(table_a);
allTable.push(table_b);
res.status(200).json({data: allTable});
}
module.exports = { contentHandler };
I recommend you to use promise like this:
async function getData(tableName) {
return new Promise(function (resolve, reject) {
db.select("*")
.from(tableName)
.then((data) => {
resolve(data);
});
});
}
async function run(){
var allTable = [];
const firstTable = await getData('testingDB');
const secondTable = await getData('user');
allTable.push(firstTable);
allTable.push(secondTable);
res.status(200).json({data: allTable});
}
run().then(() => {
console.log("Finished!");
})
I see a couple potential issues here.
Unhandled Promise rejection:
Add a catch block after then (you can rethrow to put it in the existing catch block).
.then(data => {
if(data.length){
let responseData = {}
responseData[tableName] = data
res.status(200).json(responseData)
}
})
.catch(err) {throw err}
tableName is also not going to be interpreted as variable, but as a literal property name, so I changed it to get what I think you were going for.
For the header error, you are setting the response twice, once for "services", then again for "practitioners". One possible solution is to remove the res.status... line from handler and use Promise.all in content and moving the response setting there:
const content = (req, res, db) => {
Promise.all(
handler(req, res, db, 'services')
handler(req, res, db, 'practitioners')
)
.then(allData => {
//use reduce/Object.assign to combine the individual data objects
allData.reduce((finalResponseData, data) => {
if(!data.length) return finalResponseData
Object.assign(finalResponseData, data)
})
.then(finalResponseData => res.status(200).json(finalResponseData)
.catch(err) {res.status(400).json(err)}
}

Trying to refactor a promisified function in to try-catch block

I am trying to refactor this code using try-catch blocks:
export const authorizeConnectyCube = async (accessToken) => {
const userCredentials = {
provider: 'firebase_phone',
'firebase_phone[project_id]': "xxxxxxxx",
'firebase_phone[access_token]': accessToken,
};
await createSession();
return new Promise((resolve, reject) => {
ConnectyCube.login(userCredentials, (error, user) => {
user ? resolve(user) : reject(error);
})
}).catch(error => console.log(error));
}
const createSession = () => {
return new Promise((resolve, reject) => {
ConnectyCube.createSession((error, session) => {
session ? resolve(session.user) : reject(error)
})
}).catch(error => console.log(error));
}
However I'm not getting the same result - the asynchronousity seems to be being handled differently. Here is my attempt at refactoring:
export const authorizeConnectyCube = async (accessToken) => {
const userCredentials = {
provider: 'firebase_phone',
'firebase_phone[project_id]': "xxxxxxxxxx",
'firebase_phone[access_token]': accessToken,
};
await createSession();
try {
ConnectyCube.login(userCredentials, (error, user) => {
return user;
})
}
catch (error) {
console.log(error)
}
}
const createSession = () => {
try {
ConnectyCube.createSession((error, session) => {
return session.user
})
} catch (error) {
console.log(error);
}
}
Is there any particular part of what I'm wrong? Thanks.
Callback-based APIs don't readily turn into something you can use for async/await (which under the hood uses promises). You'll have to "promisify" them first (i.e. wrap them in promises).
Here's an example of what I'm trying to say:
// Promisify these callback-based APIs.
const login = userCredentials => {
return new Promise((resolve, reject) => {
ConnectyCube.login(userCredentials, (error, user) => {
user ? resolve(user) : reject(error);
})
})
})
const createSession = () => {
return new Promise((resolve, reject) => {
ConnectyCube.createSession((error, session) => {
session ? resolve(session.user) : reject(error)
})
})
})
// Then use them in an async function
export const authorizeConnectyCube = async (accessToken) => {
const userCredentials = {
provider: 'firebase_phone',
'firebase_phone[project_id]': "xxxxxxxx",
'firebase_phone[access_token]': accessToken,
}
try {
await createSession()
return login(userCredentials)
} catch (e) {
console.warn(e)
}
}
Also, async functions return promises, with the resolved value being the return value, and the rejected value being any uncaught error thrown inside. A value wrapped in a promise as return value for an async function is redundant.
If you're using Node 8+, it has a utility called promisify which accepts a callback-based API and returns a promise-returning version of it.

Async await does not wait

I have the following in Typescript:
import sql = require("mssql");
const config: sql.config = {....
}
const connect = async() => {
return new Promise((resolve, reject) => {
new sql.ConnectionPool(config).connect((err) => {
if (err) {
reject(err);
} else {
console.log("CONNECTED");
resolve();
}
});
});
};
(async() => {
await connect().then(
() => {
console.log("Connection pool created successfully.");
}).catch((err) => {
console.error(err);
});
})();
console.log("Now proceeding to load...");
I always get the console output in the following order:
Now proceeding to load...
CONNECTED
Connection pool created successfully
What have I done wrong? How do I achieve executing the last line of code only after all the activities before it have completed execution?
You're calling the (async () => {... function, which is, well, asynchronous, and then directly proceed to print the loading message.
You're also mixing and matching .then().catch() and async/await/catch error handling – I'd refactor things like this:
import sql = require("mssql");
const connect: (config: sql.config) => Promise<sql.ConnectionPool> = async config =>
new Promise((resolve, reject) => {
const pool = new sql.ConnectionPool(config);
pool.connect(err => {
if (err) return reject(err);
console.log("CONNECTED");
resolve(pool);
});
});
const config: sql.config = {
/*...*/
};
(async () => {
console.log("Now proceeding to load...");
try {
const pool = await connect(config);
console.log("Connection pool created successfully.");
} catch (e) {
console.error(e);
return;
}
})();
Try this:
(async () => {
await connect();
console.log("Connection pool created successfully.");
})();
try something like below
import sql = require("mssql");
const config: sql.config = { /*....*/ };
const connect = () => {
return new Promise((resolve, reject) => {
try {
let Connection = await sql.ConnectionPool(config).connect();
console.log("Connected to mssql");
resolve("Successfully Connected");
} catch (error) {
reject(error);
}
});
};
(async function () {
try {
let Connection = await connect();
console.log("Connection pool created successfully.");
} catch (error) {
console.error(error);
}
}());

Categories