0

RouteHandler

function getProfile(req, res) {
    var graphs = dataSaver.getGraphs(req.user.email)
    console.log(graphs)
    res.render('profile', {
        title: 'EZgraph |  User Home',
        userGraphs: graphs
    })
}

Db code

function getGraphs(username) {
    model.findOne({
            email: username
        },
        function(err, user) {
            if (err) {
                console.log('err')
            }
            if (!user) {
                console.log('no user found!')
            } else {
                var graphs = user.savedGraphs
                console.log(graphs)
                return graphs
            }
        }
    )
}

using the above two methods I'm trying to pass data read from the DB to a jade view. The problem is that within the scope of the 2nd method that reads from the db, the object is read fine, the console.log call shows me that. Once I return this object though and return to the scope of the route handler, the variable that should be equal to the object no prints as undefined. How do I fix this?

EDIT

In repsonse to the comments I tried the following, it isn't pretty at all but I run into the same problem.

Handler + helper

function getProfile(req, res) {
    var graphs = dataSaver.getGraphs(req.user.email, readSuccess)
    console.log(graphs);
    res.render('profile', {
        title: 'EZgraph |  User Home',
        userGraphs: graphs
    })
}

function readSuccess(data) {
    return data
}

db code

function getGraphs(username, callback) {
    model.findOne({
            email: username
        },
        function(err, user) {
            if (err) {
                console.log('err')
            }
            if (!user) {
                console.log('no user found!')
            } else {
                callback(user.savedGraphs)
            }
        }
    )
}
Eogcloud
  • 1,335
  • 4
  • 19
  • 44
  • 2
    Since `.findOne()` is asynchronous, it can't `return graphs`. The code just doesn't execute in the order needed for that. A typical option is to revise `getGraphs()` to take and call a `callback`. Related: [How to return the response from an AJAX call?](http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call) While the example is Ajax with jQuery, the information can be applied to all asynchronous code, including `.findOne()`. – Jonathan Lonowski Apr 01 '14 at 18:20
  • getGraphs has no return statement. The return statement that you think is returning the correct value is actually a callback inside of model.fineOne(). – Jordan Apr 01 '14 at 18:27
  • hi guys, thanks for the replies. I added an edit to the OP. – Eogcloud Apr 01 '14 at 18:44
  • Possible duplicate of [How to return the response from an AJAX call?](http://stackoverflow.com/q/14220321/710446) (Just replace "AJAX" with "`findOne`"; they're both async and the problem is likely identical.) – apsillers Apr 01 '14 at 18:52
  • `readSuccess` has the data just fine, right? If so, you've successfully used callbacks to move the data out of `getProfile`. The missing link for your understanding here is that once you've done an async operation, you can never `return` that data; you can only use more callbacks. It's callbacks all the way down. Thus, have `readSuccess` do the actual thing you wanted to do with the data (or replace `readSuccess` with a callback passed into `getProfile`). – apsillers Apr 01 '14 at 19:01
  • Thank you, this is what I was missing. This all makes sense now. You should post this as a full answer so I can give it to you. – Eogcloud Apr 01 '14 at 19:06

0 Answers0