Node js promise result use in other function - javascript

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

Related

NodeJS: Can't return a result from a function

I'm trying to return the result from this function :
var YouTube = require('youtube-node');
var youTube = new YouTube();
youTube.setKey('XXXXXXXXXXXX');
var result = youTube.search('World War z Trailer', 2,
function(error, result) {
if (error) {
console.log(error);
} else {
return result
}})
console.log(result)
But then I only get undefined as a result in console.
You need to wait for the response.
This simple answer is to place the console.log(result) inside the callback.
Or you can wrap the search method in a promise:
var promise = new Promise((resolve, reject) => {
youTube.search('World War z Trailer', 2, function (error, result) {
if (error) {
reject(error);
}
else {
resolve(result);
}
})
});
Then you can wait for the response using .then() like this:
promise.then((result) => {
console.log(result);
}).catch((err) => {
console.error(err);
});
Or using await/async:
(async () => {
try {
const result = await promise;
console.log(result);
} catch (err) {
console.error(err)
}
})();
Last function here is a callback function, it doesn't return value in way you want. Read how it works somewhere, for example here.
Your issue could be resolved with Promise in this way
var search = new Promise(
(resolve, reject) => {
youTube.search('World War z Trailer', 2, function(error, result) {
if (error) { reject(error); }
resolve(result);
})
}
);
(async () => {
var result = await search;
console.log(result);
})()

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

Async\Await with promise not working properly

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

Print result from promise map

Hi guys I have 2 methods.
checkVenueAvailability(venues) {
var replaced = venues.replace(/\t/g, "");
var venues = replaced.split(',');
var length = venues.length;
Promise.all(venues.map(venue => {
return new Promise((resolve, reject) => {
pool.query("SELECT * FROM peminjaman_venue WHERE nama_venue = ?", venue,
function (err, rows, fields) {
if (err) {
return reject(err);
}
return resolve(rows);
})
})
}))
}
And
mengajukan_event(req, res) {
helper.checkVenueAvailability(req.body.venue_1)
.then(function (result) {
console.log(result);
}).catch(function (err) {
console.log(err);
})
}
I want to print the result of checkVenueAvailability in mengajukan_event. How to achieve that. My code above just return error. Thankyou.
You aren't returning anything. Just return the promise from Promise.all:
return Promise.all(venues.map(venue => {
// ^^^^^^
Also note that there are DB adapters with a Promise-based API available now. Or, if you can't use one, you can use util.promisify.
const promiseQuery = util.promisify(pool.query);
Then
checkVenueAvailability(venues) {
var replaced = venues.replace(/\t/g, "");
var venues = replaced.split(',');
return Promise.all(venues.map(venue => promiseQuery("SELECT * FROM peminjaman_venue WHERE nama_venue = ?", venue));
}
(I also removed var length = venues.length; since length wasn't used for anything.)

Is this a good way to run multiple mysql queries with Promise.all

So I am running a few insert queries using the mysql npm package and I'm doing so with Promise.all to try and run them at the same time. I have a function that creates a new connection for each query and returns a promise. I am also wrapping the mysql queries with promises. Here is the code that builds the queries and calls them with Promise.all
const Database = require('./database');
const queryBuilder = record =>
new Promise((resolve, reject) => {
try {
const filename = record.s3.object.key.split('/').pop();
const filesize = record.s3.object.size;
const s3path = `${record.s3.bucket.name}/${record.s3.object.key}`;
const createdAt = record.eventTime.split('T').shift();
const sql = 'INSERT INTO raw_files (filename, filesize, s3path, created_at, client_subdomain) ' +
`VALUES ('${filename}', ${filesize}, '${s3path}', '${createdAt}', '${record.s3.bucket.name}')`;
resolve(sql);
} catch (err) {
reject(err);
}
});
const connectionWrapper = (params, record) =>
new Promise((resolve, reject) => {
const db = new Database(params);
db.connect()
.then(res => queryBuilder(record))
.then(sql => db.query(sql))
.then((res) => {
db.close();
resolve(res);
})
.catch((err) => {
db.close();
reject(err);
});
});
exports.handler = (event, context, callback) => {
const connectionParams = {
host: '127.0.0.1',
port: 3306,
user: 'root',
password: 'some_password',
database: 'space_util',
};
Promise.all(event.Records.map(record => connectionWrapper(connectionParams, record)))
.then(res => callback(null, res))
.catch(err => callback(err));
};
And then here is the wrapper module
const mysql = require('mysql');
// Promise-ify the mysql connection
const Database = function Database(connectionParams) {
this.connection = mysql.createConnection(connectionParams);
};
Database.prototype.connect = function connect() {
return new Promise((resolve, reject) => {
this.connection.connect((err) => {
if (err) reject(err);
resolve();
});
});
};
Database.prototype.query = function query(sql) {
return new Promise((resolve, reject) => {
this.connection.query(sql, (err, results, field) => {
if (err) reject(err);
resolve(results);
});
});
};
Database.prototype.close = function close() {
return new Promise((resolve, reject) => {
this.connection.close((err) => {
if (err) reject(err);
resolve('Connection closed');
});
});
};
module.exports = Database;
It works, but I am curious if the way I am doing this seems like a hack or not? Specifically the way I am calling the Promise.all with a map function as the argument. I didn't know how to make an array of connectionWrappers with their params without invoking them, hence the map function in Promise.all(). Any advice would be appreciated!

Categories