Reputation: 231
In this nodejs, expressJs based project, I am not able to return data from one function
router.get('/', async(req, res) => {
const meta = getMeta();
console.log('meta', meta) // this prints the string
const reactComp = renderToString(<Index />);
res.status(200).render('pages/index', { reactApp: reactComp, title: meta })
})
function getMeta(){
console.log("I ran")
let sql = 'SELECT `title`, `description`, `keyword` FROM `metas` WHERE `url`="-"'
db.query(sql, (err, rows) => {
if(err) throw err;
console.log(rows) // this is printing the data
});
// return rows // this is not working and gives an error
return 'Coming from getMeta'
}
I simply want to return the data from the getMeta function to the first one.
Thanks for the help.
Upvotes: 0
Views: 47
Reputation: 20467
You have a few problems there, First, the end of your function where you want to return rows. Rows are not defined as they live only in the scope of the sql callback.
The next thing is that even if your rows variable was defined, the moment you return, sql has not returned the data yet so you would return some empty variable.
The reason this callback is there is to be able to wait for sql to return the data and once sql has the rows, to use them inside the callback.
The most basic implementation would look like this:
router.get('/', async(req, res) => {
const sql = 'SELECT `title`, `description`, `keyword` FROM `metas` WHERE `url`="-"'
db.query(sql, (err, rows) => {
if(err) throw err;
const reactComp = renderToString(<Index />);
res.status(200).render('pages/index', { reactApp: reactComp, title: rows })
});
})
You see, we are waiting for the data to arrive inside the callback and return our response from there.
Now, there may be fancy ways to wrap this in a promise or something:
function getMeta() {
const sql = 'SELECT `title`, `description`, `keyword` FROM `metas` WHERE `url`="-"'
// wrapping the query in a promise
return new Promise((resolve, reject) => {
db.query(sql, (err, rows) => {
if(err) reject(err);
resolve(rows)
});
})
}
// now we can use the await keyword
router.get('/', async(req, res) => {
const meta = await getMeta()
console.log('meta', meta)
const reactComp = renderToString(<Index />)
res.status(200).render('pages/index', { reactApp: reactComp, title: meta })
})
Upvotes: 0
Reputation: 17
Use promise for mysql, you can't use return
in callback function.
Try this:
function getMeta(){
return new Promise(resolve => {
console.log("I ran")
let sql = 'SELECT `title`, `description`, `keyword` FROM `metas` WHERE `url`="-"'
db.query(sql, (err, rows) => {
if(err) throw err;
console.log(rows) // this is printing the data
resolve(rows) //this will make the return
});
});
Upvotes: 1
Reputation: 116
If you're using promises you should return from inside of the function.
function getMeta () {
let sql = 'SELECT `title`, `description`, `keyword` FROM `metas` WHERE `url`="-"'
return db.query(sql, (err, rows) => { // <- Add return
if (err) throw err;
return rows // <- Add return
});
}
But also you would make it asynchronous.
function getMeta() {
(async () => {
let sql = 'SELECT `title`, `description`, `keyword` FROM `metas` WHERE `url`="-"'
try {
const result = await await db.query(sql)
if (!result) throw Error
return result
} catch (err) {
// handle error
}
})()
}
Upvotes: 0