Function not returning pg-pool results - javascript

I'm trying to use pg-pool to query a Postgresql database. And then export this data to a Node.js express rest API.
Here's my exports function.
exports.getDashboard = function(req, response, next) {
let returnData = fetchData();
return response.status(200).json(returnData);
};
Which calls fetchData();
fetchData = async function() {
let returnData = [];
returnData.languages = await getLatestLanguages();
return returnData;
};
Which calls getLatestLanguages()
getLatestLanguages = function() {
pgPool.pool.query(
'SELECT * FROM "WordLanguage" ORDER BY id DESC LIMIT 30 ;',
(error, results) => {
if (error) {
throw error;
}
return results.rows;
}
);
}
If i place a console.log(results.rows) before getLatestLanguages() returns results.rows, then I get the data logged to the console.
However the object isn't being returned to fetchData. I tested this by logging the returnData to console before it is returned to exports.getDashboard();
I believe my problem is something to do with the async nature of pg-pool so I tried making my function async with an await but that didn't help.
What am I doing wrong?

you need getLatestLanguages to return a Promise, so you can await it from the caller
getLatestLanguages = function() {
return new Promise((resolve, reject) => {
pgPool.pool.query(
'SELECT * FROM "WordLanguage" ORDER BY id DESC LIMIT 30 ;',
(error, results) => {
if (error) {
reject(error);
}
resolve(results.rows);
}
);
})
}
you also need to await fetchData(), therefore getDashboard should be async
exports.getDashboard = async function(req, response, next) {
let returnData = await fetchData();
return response.status(200).json(returnData);
};

getLatestLanguages() should return a promise. For example
getLatestLanguages = function() {
return new Promise((resolve, reject) => {
pgPool.pool.query(
'SELECT * FROM "WordLanguage" ORDER BY id DESC LIMIT 30 ;',
(error, results) => {
if (error) {
reject(error);
}
resolve(results.rows);
}
);
});
};
fetchData() is async and therefore should be awaited
exports.getDashboard = async function(req, response, next) {
let returnData = await fetchData();
return response.status(200).json({ languages: returnData.languages });
};
Also make sure that you return returnData.languages in the correct format as above instead of ...json(returnData);

Related

Function is returning before SqlQuery finishes

I have a function that has a query that connects to a database and does a basic SELECT query, The query works fine, however the function appears to be returning before the query finishes all of its steps. In this case I have the Hello World Console log and the array is undefined. But if I setTimeout for one second and then log out the "NewArray" it has all the data from the query. So my question is: How do I return this data after the query has finished doing its magic.
async function getData() {
let newArray = []
let db = new sqlite3.Database('PATHTODB',sqlite3.OPEN_READWRITE, (err) => {
if (err) {
return console.error(err.message);
}
});
let selectQuery = `SELECT * FROM TableName;`
await db.all(
`${selectQuery}`,
(err, row) => {
console.log(row)
row.forEach(x => {
newArray.push(x)
})
}
)
console.log("Hello World", newArray)
return newArray
}
Tried using ASYNC/AWAIT
db.all(query, callback) is not an async function to await. It's just invoking it's callback asynchronously. Try promisfying it as follows;
async function getData() {
let newArray = []
let db = new sqlite3.Database('PATHTODB',sqlite3.OPEN_READWRITE, (err) => {
if (err) {
return console.error(err.message);
}
});
let selectQuery = `SELECT * FROM TableName;`,
row = await new Promise((resolve,reject) =>
db.all(`${selectQuery}`, (err,row) => err ? reject(err)
: resolve(row)));
console.log(row);
row.forEach(x => newArray.push(x));
console.log("Hello World", newArray);
return newArray
}

JS async function returning undefined although calling it inside an asynchronous function

I am using nodeJs Express and I have an async function which is used in another function.
here is my code:
/* get user info */
const getUserInfo = async (req) => {
let userID = req.cookies.userId;
if(!userID) return null;
await connection.query('SELECT * FROM users WHERE id = ' + userID,
function (err, rows, fields) {
if (err) throw err
// if user not found
if (rows.length === 0) {
return null;
}
// if user found
else {
return rows[0];
}
});
}
/* display dashboard page */
router.get("/", async function (req, res, next) {
let userInfo = await getUserInfo(req);
console.log(userInfo) // It's result is undefined
if (userInfo) {
res.render('dashboard/profile', {
fullName: userInfo.fname + " " + userInfo.lname,
email: userInfo.email,
phone: userInfo.phone,
});
}
else {
res.render('authentication/register', {
title: 'ثبت نام',
});
}
});
how to resolve this problem? I need userInfo retun me some data.
await is only useful if the value on the right-hand side is a promise.
connection.query is taking a callback function, which implies it isn't returning a promise.
You need to either:
Find out how to make the API you are using return a promise (if that is possible)
Wrap the callback in a promise
Replace the API with one that supports promises natively
You also need getUserInfo to have a return statement of its own.
You have to return some value from your getUserInfo function
If connection query doesn't support promise you should wrap it like this
/* get user info */
const getUserInfo = async(req) => {
let userID = req.cookies.userId;
if (!userID) return null;
return new Promise((resolve, reject) => {
connection.query('SELECT * FROM users WHERE id = ' + userID,
function(err, rows, fields) {
if (err) {
reject(err)
return;
}
// if user not found
if (rows.length === 0) {
resolve(null)
}
// if user found
else {
resolve(rows[0]);
}
});
});
}

I'm getting an error when I search the database and I don't know how to solve it

I'm making a request to my database, I set the functions as asynchronous and to wait, but it still returns me undefined or Promise { pending }
how do I just return it when I have the result?
export const getGerente = async (req, res) => {
var query = "SELECT * FROM inventory;"
const r = await select(query)
console.log(r)
return res.json({message:"teste"})
}
export async function select(query) {
var teste = await client.connect(() =>{
client
.query(query)
.then((resultado) => {
console.log('sucess!!');
return resultado.rows
/*
const rows=resultado.rows
rows.map(x =>{
console.log(x.name)
})*/
})
.catch((erro) => {
console.log("erro: " + erro.message);
})
.then((teste) => {
console.log('Finished execution, exiting now');
process.exit();
});
})
}
result: Promise { pending }
I'm calling her for a request
Your select function is not awaiting the client.connect properly.
Try this for select function -
export async function select(query) {
const promisifiedRows = new Promise((resolve, reject) => {
client.connect((err) => {
if (err) {
reject(err); // err in connecting
} else {
console.log('Connected!');
client.query(query, (err, rows) => {
if (err) {
reject(err); // err while exceuting the query
} else {
resolve(rows);
}
});
}
});
});
const rows = await promisifiedRows();
return rows;
}

Class in Nodejs does not return expected value when using parameter

I have a class on my node server, each function of it returns something from another api, the first function that I will show does not use a parameter, it returns the items correctly, the second that uses the Make parameter, does not return anything, and does not point out error
function getInventory:
(this function works normally)
async getInventory() {
try {
let res = await axios.get(URL);
let data = res.data;
return data;
} catch (err) {
return err;
}
}
function getMakesNew(make): (this function works without errors but does not return anything)
async getMakesNew(make) {
try {
let res = await axios.get(URL);
let data = res.data;
let count = 0;
while (data != make) {
if (data[count].ID === make) {
return data[count].Name;
} else {
count++;
}
}
} catch (err) {
return err;
}
}
Calling the two functions on the routes:
// GetInventory
routes.get('/getInventory', async (req, res) => {
return res.json(await Vehicle.getInventory());
});
// getMakesNew
routes.get('/getMakesNew/:make', async (req, res) => {
let { make } = req.params;
return res.json(await Vehicle.getMakesNew(make));
});
function getMakesNew returns:
{}
return keyword is missing from your second function

variable undefined outside youtube search api function

I am fetching playlistId from youtube api .
It gives correct output when console output within the youtube search function.
It gives undefined outside youtube search api function.
var playlistId;
async function suggestTrack(genre) {
youtube.search.list({
auth: config.youtube.key,
part: 'id,snippet',
q: genre
}, function (err, data) {
if (err) {
console.error('Error: ' + err);
}
if (data) {
console.log(data.items[0].id.playlistId); //getting the id
playlistId = data.items[0].id.playlistId;
}
//process.exit();
});
console.log(playlistId);// undefined
const tracks = await youtube_api.getPlaylistTracks(playlistId);
return tracks[Math.floor(tracks.length * Math.random())];
}
The API call is asynchronous. And you are printing the value of playlistId before the response of the api even comes back. You have to wait for the response to come. And since you are using async wrap the api call in a Promise and use await. To promisify the search.list method, you have a lot of options, or you can do it yourself, like below
function search(key, part, genre) {
return new Promise((resolve, reject) => {
youtube.search.list({
auth: key,
part: part,
q: genre
}, function (err, data) {
if (err) {
reject(err);
return;
}
// use better check for playlistId here
resolve(data ? data.items[0].id.playlistId : null);
})
});
}
// then use it here
async function suggestTrack(genre) {
const playlistId = await search(config.youtube.key, 'id,snippet', genre);
const tracks = await youtube_api.getPlaylistTracks(playlistId);
return tracks[Math.floor(tracks.length * Math.random())];
}
youtube.search.list is asynchronous. You are trying to access to playlistId as it was a part of a synchronous process.
You can wrap the youtube.search.list inside a Promise to simplify it's use.
OLD WAY
function wrappedSearch() {
return new Promise((resolve, reject) => {
youtube.search.list({
auth: config.youtube.key,
part: 'id,snippet',
q: genre
}, (err, data) => {
if (err) {
console.error('Error: ' + err);
return reject(err);
}
return resolve((data && data.items[0].id.playlistId) || false);
});
});
}
async function suggestTrack(genre) {
const playlistId = await wrappedSearch();
// Here playlistId is either the playlistId, either false
console.log(playlistId);
const tracks = await youtube_api.getPlaylistTracks(playlistId);
return tracks[Math.floor(tracks.length * Math.random())];
}
NEW WAY
available in node v8 doc
tutorial
const {
promisify,
} = require('util');
const youtubeSearchAsync = promisify(youtube.search.list);
async function suggestTrack(genre) {
const data = await youtubeSearchAsync({
auth: config.youtube.key,
part: 'id,snippet',
q: genre
});
const playlistId = (data && data.items[0].id.playlistId) || false;
console.log(playlistId);
const tracks = await youtube_api.getPlaylistTracks(playlistId);
return tracks[Math.floor(tracks.length * Math.random())];
}

Categories

Resources