Async\Await with promise not working properly - javascript

I have an Async function and I send to another Async function that wait for the promise to resolve, but for some reason its not waiting for the reslove.
Router.get("/openPage/:id",async(res,req)=>{
var parms = res.getHeaderParamas();
let select = OpenTemplate(parms);
let theResualt = await select.then(data=>data);
connection.end();
res.returnJson(theResualt,"Success");
});
async function OpenTemplate(header){
return new Promise(res=>{
var query = `SELECT * FROM streamingpages WHERE ID=${header.routerParamas.id}`;
connection.connect((err)=>{res(err)});
connection.query(query,(error, results, fields)=>{
if(error) res(error)
console.log(results);
res(results);
});
})
}
I dont understand what am I doing wrong??

In this line:
connection.connect((err)=>{res(err)});
You resolve the promise when the connection was established, not when the query was done. You can't resolve a Promise more than once.
function makeQuery(connection, query) {
return new Promise((resolve, reject) => {
connection.connect(error => {
if(error) return reject(error);
connection.query(query, (error, results, fields) => {
if(error) return reject(error);
console.log(results);
resolve(results);
connection.close(); // actually you should open the connection to the db once ...
});
});
});
}
const openTemplate = header =>
makeQuery(connection, `SELECT * FROM streamingpages WHERE ID=${header.routerParamas.id}`); // MYSQL INJECTION POSSIBLE!!!!
Router.get("/openPage/:id",async(res,req)=>{
var params = res.getHeaderParams();
const result = await openTemplate(parms);
res.returnJson(result, "Success");
});

Related

Why Unexpected reserved word 'await' even when my function is declared as async?

I'm putting together some Node.js code for querying LDAP that uses promises. When I run it, I get Unexpected reserved word concerning the await on line 43. This part:
let connection = await connect(ldapURL).catch((err) => {
console.error('LDAP server error:', err);
reject(err);
});
The entire code is shown below.
I have a promise returned in the connect() function and that's working fine. In fact, if I remove the promise from the listObjects() function, the console.debug(results); line prints exactly what I'm expecting.
So why is the await connect() causing an error in my listObjects() function? My searching has yielded a lot of answers saying, "You need to use async," but I already have my listObjects() declared as async.
Where have I gone wrong?
Full Code:
#!/usr/bin/env node
import ldapjs from 'ldapjs';
const ldapURL = [ 'ldap://127.0.0.1:389' ];
const bindDN = 'uid=search,dc=home';
const bindPassword = 'P#ssw0rd';
function connect(serverURL) {
return new Promise((resolve, reject) => {
const client = ldapjs.createClient({
url: serverURL
});
client.on('connect', () => {
console.debug('Connected to:', ldapURL);
console.debug('Binding as:', bindDN);
client.bind(bindDN, bindPassword, (err) => {
if (err) {
console.debug(err.message);
reject('Bind credentials rejected.');
}
else {
resolve(client);
}
});
});
client.on('error', (err) => {
reject('Unable to connect to ' + serverURL);
});
});
}
/**
* Search LDAP and return objects.
* #baseDN {string} Where to start, like 'ou=People,dc=example,dc=com'
* #filter {string} Optional LDAP query to limit results, like '(objectClass=posixAccount)'
* #returns {promise} ... Eventually.
*/
async function listObjects(baseDN, filter) {
return new Promise((resolve, reject) => {
let connection = await connect(ldapURL).catch((err) => {
console.error('LDAP server error:', err);
reject(err);
});
let opts = {
filter: filter,
scope: 'sub'
};
let results = [];
connection.search(`${baseDN}`, opts, (err, res) => {
res.on('searchEntry', (entry) => {
results.push(entry);
});
res.on('end', () => {
connection.unbind(() => {
console.debug(results);
resolve(results);
});
});
});
});
}
let ldapObjects = await listObjects('dc=home', '(objectClass=posixAccount)');
console.log(ldapObjects);
After helpful suggestions in the comments, the solution was to Move the line return new Promise((resolve, reject) => { down so that it only wraps the connection.search(…) part as suggested by Bergi
Here is the code after that modification:
#!/usr/bin/env node
import ldapjs from 'ldapjs';
const ldapURL = [ 'ldap://127.0.0.1:389' ];
const bindDN = 'uid=search,dc=home';
const bindPassword = 'P#ssw0rd';
function connect(serverURL) {
return new Promise((resolve, reject) => {
const client = ldapjs.createClient({
url: serverURL
});
client.on('connect', () => {
console.debug('Connected to:', ldapURL);
console.debug('Binding as:', bindDN);
client.bind(bindDN, bindPassword, (err) => {
if (err) {
console.debug(err.message);
reject('Bind credentials rejected.');
}
else {
resolve(client);
}
});
});
client.on('error', (err) => {
reject('Unable to connect to ' + serverURL);
});
});
}
/**
* Search LDAP and return objects.
* #baseDN {string} Where to start, like 'ou=People,dc=example,dc=com'
* #filter {string} Optional LDAP query to limit results, like '(objectClass=posixAccount)'
* #returns {promise} ... Eventually.
*/
async function listObjects(baseDN, filter) {
let connection = await connect(ldapURL).catch((err) => {
console.error('LDAP server error:', err);
reject(err);
});
let opts = {
filter: filter,
scope: 'sub'
};
let results = [];
return new Promise((resolve, reject) => {
connection.search(`${baseDN}`, opts, (err, res) => {
res.on('searchEntry', (entry) => {
results.push(entry);
});
res.on('end', () => {
connection.unbind(() => {
resolve(results);
});
});
});
});
}
let ldapObjects = await listObjects('dc=home', '(objectClass=posixAccount)');
console.log(ldapObjects);
I think you have to remove new Promise because async return the data wraps in the Promise. I think that your ldapObjects store a Promise and listObjects return a Promise wrap inside a Promise.

How to use async/await to get data from sqlite db.each

I would like to get my data out from the sqlite db.each function using the promise object and the async/await I tried to do it but I don't really understand how to do it and I would like some explanations
my code below :
var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database('./data.sqlite', (err) => {
if (err) {
console.error(err.message);
}
console.log('Connected to the database');
});
function request (req) {
new Promise(function (resolve, reject) {
db.each(req, function (err, row) {
if (err)
reject(err);
else
data.push(row);
}, function (err, n) {
if (err) {
reject(err);
}
else
resolve(data);
});
});
}
data = await request("select * from user "); //I'm getting errors here
db.close((err) => {
if (err) {
return console.error(err.message);
}
console.log('Close the database connection');
});
await can only be used inside an async function. Create an async function, inside this function, await the promise returned by request function
async function makeRequest() {
data = await request("select * from user ");
}
and you need to return the promise from request function so that it can be awaited
function request (req) {
return new Promise(function (resolve, reject) {
// code
});
}

What is the syntax to using await and async in asynchronous functions using nodejs?

I am trying to create a basic API in nodejs to perform CRUD actions on a database.
I do not understand why the result is undefined
exports.getPlaylist = async function (req, res) {
console.log('Recieved getPlaylist request');
result = await connection.executeQuery('SELECT * from Users');
res.status(200).send(result);
console.log(result); // Logs undefined
};
This is the function that gets called and gets the data from the database:
async executeQuery(query) {
connection.query(query, function (err, result) {
if (err) {
console.log('Error executing query: ' + err);
}
console.log(result); // logs correct data
return result;
});
}
You need to "promisify" your callback. (see require('utils').promisify ) for a shorthand for applying to functions that follow node.js callback style (function(err,result){}).
executeQuery(query) {
return new Promise((res, rej) => {
connection.query(query, function (err, result) {
if (err) {
console.log('Error executing query: ' + err);
rej(err)
} else {
console.log(result); // logs correct data
res(result);
}
});
});
}
Now inside an async function you can await executeQuery(query)
The execute is not a promise base function, you cannot use await on a callback function.
change the execute function to promise base
Example:
executeQuery(query) {
return new Promise( (resolve, reject) => {
connection.query(query, function (err, result) {
if (err) {
console.log('Error executing query: ' + err);
reject('Error executing query: ' + err);
}
console.log(result); // logs correct data
resolve(result);
});
});
}
Add try catch in your calling function
exports.getPlaylist = async function (req, res) {
console.log('Recieved getPlaylist request');
try{
result = await connection.executeQuery('SELECT * from Users');
res.status(200).send(result);
console.log(result); // Logs undefined
} catch(error) {
console.log(error)
}
};

why is await not working even when used in async function

I made a function to search a user by email id. I'm calling that function in an async function using await and assigning the returned value to or constant/variable but getting undefined on printing the constant/variable
function search(email) {
sql = `SELECT email FROM users WHERE email = '${email}'`;
db.query(sql, (err, res) => {
if (err) {
console.log(err);
}
else {
return res[0].email;
}
})
}
const auth = async (req, res, next) => {
try {
const token = req.header('Authorization').replace('Bearer', '');
const decoded = jwt.verify(token, 'catisdoguniversaltruth');
const user = await search(decoded._id);
console.log(user);
if (!user) {
throw new Error();
}
next();
}
catch (e) {
res.status(401).send("Not Authenticated, Please login");
}
};
module.exports = auth;
You need search() to be a promise and not a function.
await waits for a promise to resolve.
Try this:
function search(email) {
return new Promise((resolve, reject) => {
sql = `SELECT email FROM users WHERE email = '${email}'`;
db.query(sql, (err, res) => {
if (err) {
reject(err);
}
else {
resolve(res[0].email);
}
})
})
}
This will be resolved as promise and auth() will wait.
You could also build search() as async/await promise. Doesn't really matter as long as you return a promise resolve.

Node js promise result use in other function

I am new in node js and i need result of my first query as a parameter in another function.
Here my model:
return new Promise((resolve, reject) => {
var sql = "SELECT * FROM table";
db.query(sql,
(err, result) => {
if (err) {
return reject(err)
}
return resolve(result)
});
});
I need something like this
return new Promise((resolve, reject) => {
var sql = "SELECT * FROM table";
db.query(sql)
.then(rows.map(row =>{
return arr[row.id] = this.getProduct(row.id);
}))
})
Use Async/Await.
You can make a generic queryDb function which will call db and fetch result for any query.
mainFunction will wait for await to finish and fetch result which you can use in line below it.
Code also looks clean and easy to understand.
Something like this,
async function mainFunction(){
try{
const query = `INSERT INTO aaa xxxxxx`;
const result = await queryDb(query);
//do whatever with the result;
this.getProduct(result);
}
catch(e){
//catch error
}
}
function queryDb(sql){
return new Promise( ( resolve, reject ) => {
db.query(sql,
(err, result) => {
if (err) {
return reject(err)
}
return resolve(result)
});
})
}

Categories