0

I have a route written in Express as the following:

app.get("/route", function(req, res){
    if (someBoolean){
        someFunction(stuff, function(user){
            ...
            req.session.user = user;
        }); 
    }
    res.render("route");
}

When someBoolean is true, the session should be set. However, after moving on to a different page, req.session.user comes back as undefined. Checking req.session.user inside someFunction comes back defined however. A solution I have found to the session becoming undefined outside the scope of someFunction was to move res.render("route") into someFunction as such:

app.get("/route", function(req, res){
    if (someBoolean){
        someFunction(stuff, function(user){
            ...
            req.session.user = user;
            res.render("route");
        }); 
    }
}

This however causes the route to fail when someBoolean is false. I'm thinking this is caused by the asynchronous nature of Node.js, but I am not sure. What is causing this to occur exactly, and is this the proper solution?

alibman
  • 33
  • 6
  • Can you post the contents of `someFunction`? This is actually important in determining whether Node's asynchronous nature is causing this issue. – Mike Jul 13 '15 at 23:03
  • I don't have the exact code with me right now, but someFunction involves writing/reading from a database, so that is why I assumed it must be caused by the async nature of Node. – alibman Jul 14 '15 at 04:00
  • Yes, that is exactly the reason why if it is reading/writing to a database. You must perform any action you want to happen upon completion of the db call in a callback method to ensure that the events happen in order. – Mike Jul 14 '15 at 04:43

2 Answers2

3

simplest solution would be:

app.get("/route", function(req, res){
    if (someBoolean){
        someFunction(stuff, function(user){
            ...
            req.session.user = user;
            res.render("route");
        }); 
    }else{
        res.render("route");
    }
}

using promises you can do it like ( first you promisify someFunction):

app.get("/route", function(req, res){
    Promise.resolve()
      .then(function(){
          if(someBoolean){
            return someFunction(stuff)
              .then(function(user){
                res.session.user = user;
              });
          }
      }).then(function(){
        res.render("route");
      });
}
mido
  • 20,728
  • 10
  • 84
  • 109
  • 1
    Your first example does what I was looking for. It took me a while to find, so I'm typing my question here so others might find it faster than I did: "how to pass data from a function with a callback to the express router". – Max Aug 17 '17 at 12:06
2

Session states are saved in one of two conditions -

  1. When a response is sent (through res.send, res.redirect, etc.),

  2. you manually call req.session.save()

Simon Poole
  • 475
  • 6
  • 15