Amit Khare
Amit Khare

Reputation: 231

not able to return data from a function

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

Answers (3)

The Fool
The Fool

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

LoboMetalurgico
LoboMetalurgico

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

Mykhaylo Gusak
Mykhaylo Gusak

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

Related Questions