aws lambda function async connection query - node.js

I have a function connect to amazon RDS and select data from a table, but my callback function always return result is undefined. I used async/await for this function but it does't work.
My problem: I need function getOrder must be finished and return a result, after that call to callback.
My function:
'use strict';
let mysql = require('mysql');
let config = require('./config');
let pool = mysql.createPool({
connectionLimit : 10,
host : config.host,
user : config.user,
password : config.password,
database : config.database
});
exports.handler = async (event, context, callback) => {
let result = {};
try{
let sql = "SELECT * FROM tbl_test WHERE deleted = ? ";
result = await getOrder(sql,0);
}catch (err){
throw new Error(err);
}
console.log("-----Result: ",result);
return callback(null, {body: JSON.stringify(result),statusCode:200});
};
let getOrder = async (sql, params) => {
pool.getConnection((err, connection) => {
connection.query(sql, params, (err, results) => {
if (err){
throw new Error(err);
}
console.log("-----Query Done!");
connection.release();
console.log("-----Data: ", results);
return results;
});
});
};
Result when run:
result of function

To get it works, in your getOrder async function you should return a promise.
Ex:
let getOrder = async (sql, params) => {
return new Promise((resolve, reject) => {
pool.getConnection((err, connection) => {
connection.query(sql, params, (err, results) => {
if (err){
reject(err);
}
console.log("-----Query Done!");
connection.release();
console.log("-----Data: ", results);
resolve(results);
});
});
});
};

Related

Not able to return value from promise in Nodejs

I have written the following code in Nodejs which is saving data in MongoDB:
function insertDoc(db,data){
return new Promise(resolve => {
callback=db.collection('AnalysisCollection').insertOne(data).then(function(response,obj){
console.log("Inserted record");
resolve(obj);
//console.log(obj);
// response.on('end',function(){
// resolve(obj);
// });
//return resolve(obj);
}).then(() => { return obj }
).catch(function(error){
throw new Error(error);
});
})
}
I am calling the above function from the main function like this:
async function cosmosDBConnect(nluResultJSON){
try{
//console.log("Inserting to cosmos DB");
console.log(nluResultJSON);
var url = config.cosmos_endpoint;
var result="";
var data = JSON.parse(JSON.stringify(nluResultJSON));
MongoClient.connect(url, function(err, client) {
assert.equal(null, err);
var db = client.db('NLUAnalysisDB');
// insertDoc(db, data, function() {
result=insertDoc(db, data, function() {
console.log(result);
client.close();
//return data._id;
});
});
}
catch (e) {
console.log(e);
}
}
module.exports = { cosmosDBConnect };
But in cosmosDBConnect, I am getting 'undefined' for the result, though in insertDoc I am getting the output for'obj' with _id for the inserted record.
Please help me to return this _id to cosmosDBConnect.
You are use callbacks inside of async function, which creates internal scopes. So your return aplies to them instead of whole function. You should use Promise-based methods inside of async function using await (without callbacks) or wrap whole function into own Promise otherwise.
Example:
function cosmosDBConnect(nluResultJSON) {
return new Promise((resolve, reject) => {
var url = config.cosmos_endpoint;
var result = '';
var data = JSON.parse(JSON.stringify(nluResultJSON));
MongoClient.connect(url, function(err, client) {
if (err) return reject(err);
assert.equal(null, err);
var db = client.db('NLUAnalysisDB');
insertDoc(db, data).then(obj => {
console.log(obj);
client.close();
return resolve(data._id);
});
});
});
}
Also you need to understand that your insertDoc return Promise and do not accept callback you tried to pass.
Ref: async function
result = insertDoc(db, data).then((data) => {
console.log(data);
}).catch(err => console.error(err));

Await Promise.all async does't work in my code

I have a lambda function with the structure below,
It used to work in older versions of nodejs but it doesn't work with the newer versions.
I know my code structure is quite messy and wrong but I can't get my head around it. I'm trying to use Promise.all but I'm obviously doing something wrong cause it's not getting executed at all.
By the way, I'm not getting any errors. The promise.all method never gets executed.
let AWS = require('aws-sdk');
exports.handler = async(event, context, callback) => {
let result = {};
try {
result = await getOrder(sql, 0);
result.map(
(dataField) => {
});
}
catch (error) {
console.log(error);
callback(error);
}
var today_result = [];
const groupKey = i => i.user_id + '_' + i.when;
const counts = _.countBy(followingsIDs, groupKey);
const isMulti = i => counts[groupKey(i)] > 1;
const multiPropkey = i => ({ multiplekey: isMulti(i) ? groupKey(i) : groupKey(i) });
const multiProp = i => ({ multiple: isMulti(i) ? counts[groupKey(i)] : 1 });
const updated = _.map(followingsIDs, i => _.extend(i, multiProp(i), multiPropkey(i)));
const uniqResult = _.uniq(updated, function(d) { return d.multiplekey });
// Doesn’t execute from here —>
await Promise.all(uniqResult.map(async(dataField) => {
console.log("test_");
dosomething()
if (true) {
let sql = `INSERT INTO ….`
result = await getOrder(sql, 0);
try {
const data = await sns.publish(params).promise();
}
catch (e) {
console.log(e.stack);
response.result = 'Error';
}
}
}));
// Till here <----
callback(null, uniqResult);
};
let getOrder = async(sql, params) => {
return new Promise((resolve, reject) => {
pool.getConnection((err, connection) => {
if (err) throw err;
connection.query(sql, params, (err, results) => {
if (err) {
reject(err);
}
// console.log("-----Query Done!");
connection.release();
// console.log("-----Data: ", results);
resolve(results);
});
});
});
};
What are you awaiting to? The uniqResult is just declared as an empty array. Immediately after that you pass it to Promise.all. You need to fill it with Promises and then pass it to Promise.all.

Nodejs module export, wait for function to finish

I am developping an app using node js
in my export_db.js where I export the connection and query function
When I call the function, inside the export_db the output is really a string filled with information, but in my main.js the output is undefined, as if the function wasn't finished and the code continue to run before the results comes in.
How can I force it to wait ?
File export_db.js
var con = mysql.createConnection({
....
});
con.connect(function(err) {if (err) throw err;});
con.CustomQuery = function(SQLQuery){
..DO Stuff
return stringoutput="";
con.query(SQLQuery, function (err, result,fields) {
if (err) throw err;
var arr = result;
//Do Stuff Transform result into a String
stringoutput=result as string
});
return string output;
});
module.exports = con;
File import_db.js
var db = require('../db/export_db_connection');
//DO Stuff
Queryresult = db.CustomQuery(SQLQuery);
bot.reply(Queryresult) // Send the String to the bot to get a response message
//DO Stuffs
Since your code is fundamentally asynchronous in nature (you have to wait for it to be ready). It might be better to change your _db.js to export a factory function which returns a promise which resolves with an instance of the connection when it is available.
// _db.js
function connect() {
return new Promise(function (resolve, reject) {
var con = mysql.createConnection({
//....
});
con.CustomQuery = function (SQLQuery) {
return new Promise(function(resolve, reject){
con.query(SQLQuery, function(err, result, fields){
if(err) return reject(err)
// var str = convert result to string here
resolve(str);
})
})
};
con.connect(function (err) {
if (err) return reject(err);
resolve(con)
});
})
}
let conn = null;
function getConnection() {
if (!conn) {
conn = connect();
}
return conn;
}
module.exports = getConnection;
And then, when you want to use the connection:
var getConnection = require('/path/to/_db.js');
getConnection()
.then(function (conn) {
return conn.CustomQuery(sqlQuery)
})
.then(function(str){
// Query result is available here
console.log(str);
})
You can also do this without Promises using callbacks
// _db.js
function connect(cb) {
var con = mysql.createConnection({
//....
});
con.CustomQuery = function (SQLQuery) {
//..DO Stuff
// return stringoutput="";
};
con.connect(function (err) {
if (err) return cb(err);
cb(null, con)
});
})
}
let conn = null;
function getConnection(cb) {
if (!conn) {
return connect(function(err, con){
if(err) return cb(err);
conn = con;
cb(null, conn);
});
}
cb(null, conn);
}
module.exports = getConnection;
And then, when you want to use the connection:
var getConnection = require('/path/to/_db.js');
getConnection(function (err, conn) {
if(err){
// handle errors
}
QueryResult = conn.CustomQuery(SQLQuery);
})

Access Function in a Exported Module

I would like to create a module, where i have a function where i can insert a sql statement and get the result as recordset. Im new to nodeJs and have some trouble in accessing the functions right.
my Modul (sql.js)
var exports = module.exports = {};
sql = require('mssql');
let config = {
user: '###',
password '###'
server: '###',
database: '###',
driver: "###",
options: {
trustedConnection: true
}
};
var db = function (query) {
var rc;
console.log('verbinde');
sql.connect(config, function (err) {
console.log('verbinde');
if (err) console.log(err);
let request = new sql.request();
request.query(query, function (err, recordset) {
if (err) console.log(err);
console.log(recordset);
rc = recordset;
});
})
sql.close();
}
exports.db = db;
call
const ipc = require('electron').ipcMain;
const sql = require('../../customModules/sql.js');
console.log(sql.db('SELECT * FROM devices'));
i get an undefined.
it seems like, the sql.connect isnt rly called.
You might get better results using a Promise. Perhaps something like this (untested):
// sql.js
var db = (query) => new Promise((resolve, reject) => {
console.log('verbinde');
sql.connect(config, function (err) {
console.log('verbinde');
if (err) reject(err);
let request = new sql.request();
request.query(query, function (err, recordset) {
if (err) reject(err);
console.log('got those records!');
resolve(recordset);
});
})
sql.close();
})
// call
const ipc = require('electron').ipcMain;
const sql = require('../../customModules/sql.js');
sql.db('SELECT * FROM devices')
.then(data => console.log(data))
.catch(e => console.log(e));

Why Variable is undefined in nodejs express

I am using node js express and calling model from the controller.When I call model form controller and getting a result in result variable and print it in console.log(result) it's undefined.
Controller
var user_model=require('../models/user');
exports.get_user = function(req, res) {
var result = user_model.get_users();
console.log(result);
}
Model
var connection=require('../config/connection');
exports.get_users = function() {
connection.query('SELECT * FROM users', function(err, rows) {
if(err) {
retrun err;
}
return rows;
});
}
This is happening because you are consoling the result before the query has finished. Node is asynchronous. Unlike php node doesn't wait for the query to finish before going to the next line.
Use promise to handle async calls
// **Controller**
var user_model = require('../models/user');
exports.get_user = function (req, res) {
user_model.get_users().then((result) => {
console.log(result);
}).catch(err => console.log(err));
}
// **Model**
var connection = require('../config/connection');
exports.get_users = function () {
return new Promise((resolve, reject) => {
connection.query('SELECT * FROM users', function (err, rows) {
if (err) {
reject(err);
}
resolve(rows);
});
}
})
}

Resources