Adding async await in node js - node.js

I am using node js function i have written the code long before but i need to add async and await in my functions i don know how to proceed with my code structure .
Here is my code structure
app.express.get('/api/member/logout', function (request, response) {
functionBal.logout(request.query.abc).then(function (result) {
if (result) {
response.set('Content-Type', 'application/json');
response.status(200);
response.json(result);
}
}).catch(function (err) {
response.set('Content-Type', 'application/json');
response.status(400);
response.json("Error -- " + err);
});
});
module.exports.log = function (abc) {
return new app.promise(function (resolve, reject) {
functionDal.log(abc).then(function (result) {
if (result)
resolve(result);
else {
reject("Error");
}
}).catch(function (err) {
reject(err);
});
})
};
module.exports.log = function (abc) {
return new app.promise(function (resolve, reject) {
mySqlConnection.connection().then(function (con) {
con.query("UPDATE member SET table1 = 0 WHERE abc = ?", [abc]).then(function (rows, fields) {
resolve('success');
}).catch(function (err) {
reject(err);
});
}).catch(function (err) {
reject(err);
});
});
}
Please help in adding async await in this coding structure

Give this is try.
app.express.get('/api/member/logout', async function (request, response) {
try {
let data = await functionBal.logout(request.query.abc)
response.set('Content-Type', 'application/json');
response.status(200);
response.json(result);
} catch (error) {
response.set('Content-Type', 'application/json');
response.status(400);
response.json("Error -- " + err);
}
});
module.exports.log = async function (abc) {
try {
return await functionDal.log(abc)
} catch (error) {
throw error
}
};
module.exports.log = async function (abc) {
try {
const con = await mySqlConnection.connection()
await con.query("UPDATE member SET table1 = 0 WHERE abc = ?", [abc])
return 'success'
} catch (error) {
throw error
}
}
Make sure, you have Node.js 8+.

Related

Transaction Global in Node-Firebird

I'm using "node-firebird" in my Firebird 2.5 project and I would like to use a single transaction for multiple inserts or update in some batches, but I couldn't use a global transaction. Could someone help me with this?
This is the single form in the official example:
Firebird.attach(options, function(err, db) {
if (err)
throw err;
// db = DATABASE
db.transaction(Firebird.ISOLATION_READ_COMMITED, function(err, transaction) {
transaction.query('INSERT INTO users VALUE(?,?)', [1, 'Janko'], function(err, result) {
if (err) {
transaction.rollback();
return;
}
transaction.commit(function(err) {
if (err)
transaction.rollback();
else
db.detach();
});
});
});
});
I trying this
const NewTransaction=()=>{
return new Promise((resolve, reject) => {
firebirdPool.get((err, db) => {
if (err) {
reject(err);
return;
}
DBGlobal=db;
DBGlobal.transaction(Firebird.ISOLATION_READ_COMMITED,
function(err, transaction) {
//here i trying save the transaction
TransactionGlobal=transaction;
if (err) {
reject(err);
return;
}
resolve(TransactionGlobal)
});
});//firebirdpool
});//promisse
}//function
const CommitTransaction=()=>{
return new Promise((resolve, reject) => {
TransactionGlobal.commit(function(err) {
if (err){
transaction.rollback();
reject(err);
return;
}
else {
DBGlobal.detach();
resolve(true);
}
});//transaction
});//promisse
}
const RollbackTransaction=()=>{
return new Promise((resolve, reject) => {
try{
TransactionGlobal.rollback();
resolve(true);
}
catch(err){
reject(err)
}
});//promisse
}
//usado com commit
const QueryExecTransaction = (sql,arrayparams=[]) => {
return new Promise((resolve, reject) => {
TransactionGlobal.query(sql,arrayparams,function(err, result) {
if (err) {
console.log('erro na execução da query');
TransactionGlobal.rollback();
reject(err);
return;
}
resolve(result);
return;
});//query
});//promisse
}
I run with this test
async function test(){
await NewTransaction();
console.log('Transacao Global',TransactionGlobal);
QueryExecTransaction(`insert into tabparametros(codigo,nome,valor) values (0,'teste1','')`);
CommitTransaction();
}
test();
But i received this error:
(node:9232) UnhandledPromiseRejectionWarning: Error: invalid transaction handle (expecting explicit transaction start)
I managed to solve, the alteration was in "commitretaining" and others small alters
below the code
//variaveis de "ambiente" salvas na raiz do projeto
//.env e .env.testing
require('dotenv').config({
path: (process.env.NODE_ENV === "test")||(process.env.NODE_ENV === "development") ? ".env.testing" : ".env"
})
var Firebird = require('node-firebird');
var fs = require('fs');
var options = {};
options.host = process.env.DB_HOST;
options.port = process.env.DB_PORT;
options.database = process.env.DB_DATABASE;
options.user = process.env.DB_USER;
options.password = process.env.DB_PASSWORD;
options.lowercase_keys = false; // set to true to lowercase keys
options.role = null; // default
options.pageSize = 4096; // default when creating database
//console.log(options);
//Conexao
// 5 = the number is count of opened sockets
var firebirdPool = Firebird.pool(5, options);
const NewTransaction=()=>{
return new Promise((resolve, reject) => {
firebirdPool.get((err, db) => {
if (err) {
reject(err);
return;
}
//aqui eu salvo o DB retornando
//DBGlobal=db;
db.transaction(Firebird.ISOLATION_READ_COMMITED,
function(err, transaction) {
//aqui eu salvo a transacao retornada
//TransactionGlobal=transaction;
if (err) {
reject(err);
return;
}
resolve({transaction,db});
});
});//firebirdpool
});//promisse
}//function
const CommitTransaction=(transaction,db)=>{
return new Promise((resolve, reject) => {
transaction.commitRetaining(function(err) {
if (err){
transaction.rollback();
reject(err);
return;
}
else {
db.detach();
resolve(true);
}
});//transaction
});//promisse
}
const RollbackTransaction=(transaction,db)=>{
return new Promise((resolve, reject) => {
try{
transaction.rollback();
db.detach();
resolve(true);
}
catch(err){
reject(err)
}
});//promisse
}
//usado com commit
const QueryExecTransaction = (transaction,sql,arrayparams=[]) => {
return new Promise((resolve, reject) => {
transaction.query(sql,arrayparams,function(err, result) {
if (err) {
console.log('erro na execução da query');
transaction.rollback();
reject(err);
return;
}
resolve(result);
return;
});//query
});//promisse
}
async function testa(){
const {transaction,db}=await NewTransaction();
//console.log('Transacao Global',transaction);
let psql='';
try{
for (let i=1;i<101;i++){
psql=`insert into tabparametros(codigo,nome,valor) values (0,'teste${i}-${new Date()}','')`
if (i==79){
//psql='forcando o erro';
}
await QueryExecTransaction(transaction,psql);
}
await CommitTransaction(transaction,db);
}
catch(e){
console.log('Erro no SQL');
console.log(e);
await RollbackTransaction(transaction,db);
}
console.log('Finalizado')
}
testa();

Async loop didn't wait

I am using node-async-loop for asyncronous programming
var array = ['item0', 'item1', 'item2'];
asyncLoop(array, function (item, next)
{
do.some.action(item, function (err)
{
if (err)
{
next(err);
return;
}
next();
});
}, function (err)
{
if (err)
{
console.error('Error: ' + err.message);
return;
}
console.log('Finished!');
});
Like this I am using three async loops one under one.
I want to send the response only after the third inner loop ends. How can I do so?.
Here is the link for node-async-loop (https://www.npmjs.com/package/node-async-loop)
here is my code which i writing but whnever i want to response when the last loop completes it say can set header after send to cliend.
also in console log i am getting data every time when data coming from query.
const id = req.params.id;
finalData = [];
tb_user.findOne({ where: { id: id } }).then((userRiverSys, err) => {
if (userRiverSys) {
// console.log(userRiverSys.regionJson)
asyncLoop(userRiverSys.regionJson, function (item, next) {
// console.log("item", item);
tb_riverSystems.findAll(
{
where: { regionId: item.id }
}).then((findriverSys, err) => {
if (err) {
next(err);
return;
}
// console.log("findriverSys", findriverSys);
if (findriverSys) {
asyncLoop(findriverSys, function (item1, next1) {
if (err) {
next(err);
return;
}
// console.log("item1", item1.dataValues);
tb_facilities.findAll(
{
where: { riverSystemId: item1.dataValues.id }
}).then((findFacilities) => {
if (findFacilities) {
// console.log("findFacilities", findFacilities[0].dataValues.name);
asyncLoop(findFacilities, function (item2, next2) {
if (err) {
next(err);
return;
}
tb_userAccess.findAll(
{
where: { facilityId: item2.dataValues.id }
}).then((userAccessFacilities, err) => {
// console.log("userAccessFacilities", userAccessFacilities[0].dataValues);
// var i = 0;
asyncLoop(userAccessFacilities, function (item3, next3) {
finalData.push({
UserId: item3.userid,
facilityId: item3.facilityId,
})
next3();
},
function (err) {
if (err) {
console.error('Error: ' + err.message);
return;
}
// i++;
// console.log('Finished!!!!');
// if (userAccessFacilities.length === i) {
// console.log("finalData", i);
// // res.json({"status":"true", "message":"update OrgChallenge"})
// }
})
return res.json({"status":"true", "message":"update OrgChallenge"})
// console.log("finalData", finalData);
})
next2();
}, function (err) {
if (err) {
console.error('Error: ' + err.message);
return;
}
console.log('Finished!!!');
});
}
});
next1();
}, function (err) {
if (err) {
console.error('Error: ' + err.message);
return;
}
console.log('Finished!!');
});
}
});
next();
}, function (err) {
if (err) {
console.error('Error: ' + err.message);
return;
}
console.log('Finished!');
});
} else {
console.log("err3", err)
}
})
If you promisify your asynchronous action (so it returns a promise), then you can just use a regular for loop and async/await and there is no need for a 3rd party library to sequence your asynchronous loop. This is modern Javascript:
const { promisify } = require('util');
do.some.actionP = promisify(do.some.action);
async function someFunction() {
const array = ['item0', 'item1', 'item2'];
for (let item of array) {
let result = await do.some.actionP(item);
// do something with result here
}
return someFinalResult;
}
someFunction().then(result => {
console.log(result);
}).catch(err => {
console.log(err);
});
FYI, in real code, many (or even most) asynchronous operations now offer promisified versions of their API already so usually you don't even need to do the promisify step any more. For example, pretty much all databases already offer a promise interface that you can just use directly.
const loop = async (arr, results = []) => {
const item = arr.shift()
if (!item) {
console.log("DONE");
return results;
}
// as async function
await new Promise(resolve => {
resolve(results.push(`asynced-${item}`))
})
return loop(arr, results);
}
(async () => {
const result = await loop(["item0", "item1", "item2"])
console.log(result);
})();
I'd be happy if I can help you.
but this script uses a recursive function instead of node-async-loop.
so this might not be suitable for you.

In nodejs ,how to use async/await instead of resolve promises through ''then" in transactions?

Here is the transaction code, where I'm using promises and then method.
Using promise/then to resolve the promises, I tried to use await in this but it gives me an error that "await" is a reserved word.
e.g:
const deleteNetValues =await this.deleteNet(aId, conn);
How we can use async-await in this code? I want to get rid of then.
Your reply will be much appreciated.
Now here is the code:
return new Promise(function (resolve, reject) {
try {
conn.beginTransaction(function (err) {
if (err) {
let res = { "success": false, "message": err.message }
resolve(res);
return false;
}
const aDetails = checkADetails(aId, conn).then(result => {
if (result.length > 0) {
const updateAsset = updateAssetDetails(
given_name,
location,
desc,
aId, conn)
}
});
conn.commit(function (err) {
if (err) {
conn.rollback(function () {
console.log(err)
let res = { "success": false, "message": err.message }
resolve(res)
return false
});
}
console.log('Transaction Complete.');
conn.end();
});
const res = { "success": true, "message": "Net details updated successfully" };
resolve(res);
});
} catch (e) {
console.log(e)
return (e);
}
})
To use Await you need to be in an Async function
conn.beginTransaction(async function (err) {
if (err) {
let res = { "success": false, "message": err.message }
resolve(res);
return false;
}
const deleteNetValues = await deleteNet(aId, conn);
let netData= someData;
netData.forEach( netAddress =>
{
const inserNet = inserteNetValue(netAddress, aId, conn);
});
//delete all dn
const deleteDNvalues = deleteDN(aId, conn);
let dnData = nameDescData;
dnsData.forEach( dnAddress => {
const addDNvalues = insertDNValue(dnAddress, aId, conn);
});
const aDetails = checkADetails(aId, conn).then(result => {
if (result.length > 0) {
const updateAsset = updateAssetDetails(
given_name,
location,
desc,
aId, conn)
}
});
conn.commit(function (err) {
if (err) {
conn.rollback(function () {
console.log(err)
let res = { "success": false, "message": err.message }
resolve(res)
return false
});
}
console.log('Transaction Complete.');
conn.end();
});
const res = { "success": true, "message": "Net details updated successfully" };
resolve(res);
});
More informations
https://javascript.info/async-await#await

Boolean not set to true node.js

I have this code:
at the beginning of the file I initialized the variable (var loginState = false;)
Why console.log give me false, although I change it to true
try {
const client = new SimpleGraphClient(tokenResponse.token);
const me = await client.getMe();
sql.connect(config, async function (err){
if (err) console.log(err);
var request = new sql.Request();
request.query(`SELECT * FROM tradebot.accounts WHERE username='${username}' AND password='${password}'`, async function (err, recordset){
if (err) console.log(err);
console.log(recordset);
if (recordset.recordset.length == 1) {
loginState = true;
} else {
loginState = false;
}
sql.close();
});
});
console.log(loginState);
if (loginState == true) {
await turnContext.sendActivity({
text: 'Work',
attachments: [CardFactory.adaptiveCard(mainmenu)]
});
} else {
await turnContext.sendActivity({
text: 'Dont work',
attachments: [CardFactory.adaptiveCard(internal_login)]
});
}
} catch (error) {
throw error;
}
Put that console.log() inside sql.connect()`, it works the way you are expecting.
sql.connect() is an asynchronous method, so by the time the console.log() happens the sql.connect() doesn't have changed the variable value yet.
loginState = false; // Statement 1
sql.connect(config, async function (err) { // Statement 2
loginState = true;
})
console.log(loginState); // Statement 3
The order of execution of above will be,
Statement 1
Statement 3
Statement 2
So that's why it happens.
Change the code as follows for it to work fine.
try {
const client = new SimpleGraphClient(tokenResponse.token);
const me = await client.getMe();
sql.connect(config, async function (err) {
if (err) console.log(err);
var request = new sql.Request();
request.query(`SELECT * FROM tradebot.accounts WHERE username='${username}' AND password='${password}'`, async function (err, recordset) {
if (err) console.log(err);
console.log(recordset);
if (recordset.recordset.length == 1) {
await turnContext.sendActivity({
text: 'Work',
attachments: [CardFactory.adaptiveCard(mainmenu)]
});
} else {
await turnContext.sendActivity({
text: 'Dont work',
attachments: [CardFactory.adaptiveCard(internal_login)]
});
}
sql.close();
});
});
} catch (error) {
throw error;
}
Hope this helps!
The reason is because you are setting the value to variable inside a callback function :
You have to await your query result. The way you are calling the query is not feasible.
Take a look at - https://www.npmjs.com/package/mysql2
Also change this part -
sql.connect(config, async function (err){
if (err) console.log(err);
var request = new sql.Request();
request.query(`SELECT * FROM tradebot.accounts WHERE username='${username}' AND password='${password}'`, async function (err, recordset){
if (err) console.log(err);
console.log(recordset);
if (recordset.recordset.length == 1) {
loginState = true;
} else {
loginState = false;
}
sql.close();
});
});
Change this to something like this :
try{
let connection = await sql.connect(config);
let query1 = await connection.query(`SELECT * FROM tradebot.accounts WHERE username='${username}' AND password='${password}'`);
if (query1[0].recordset.length == 1) {
loginState = true;
} else {
loginState = false;
}
}catch (err){
// do something here
}

Promise.all().then() - then() executes before all() completed

In a gulp task I have the following code that creates an array of gitAction promises that get executed within a Promise.all() statement. Afterwards, I'm calling a further statement in a then(). But the then() is being called before the git pulls in the all() have terminated. Any clues please?
var git = require('gulp-git');
var gitActionPromise = function(repo, url) {
console.log('git action '+repo);
var pathToRepo = './repos/'+repo;
if (fs.lstatSync(pathToRepo).isDirectory()) {
return new Promise((resolve, reject) => {
git.pull('origin', 'master', {cwd: pathToRepo}, function (err) {
console.log(repo + " pull done!");
if (err) {
console.log('error');
reject(err);
} else {
console.log('ok');
resolve();
}
})
})
} else {
return new Promise((resolve, reject) => {
git.clone(url, {cwd: pathToRepo}, function (err) {
console.log(repo + " clone done!");
if (err) {
console.log('error');
reject(err);
} else {
console.log('ok');
resolve();
}
})
})
}
};
var repos = package.repos || {};
var promises = Object.keys(repos).map(function(repo) {
return gitActionPromise(repo, repos[repo]);
});
Promise.all(promises).then(
console.log('something else') <= this line was causing my issue
); needed to be enclosed in function
You have to pass a function to then:
Promise.all(promises).then(function() {
console.log('something else');
});
The code you have simply logs "something else" right away.

Resources