-1

I have a global variable in my server side code inside a post route and i am trying to access it within another post route. The code executes perfectly when the second post route is called for the first time, but when the second post route is triggered a second time, the value of the global variable becomes undefined.

Snippet of first post route that declares the global variable:

app.post("/login", function(req, res) {
    ...
    fs.readFile('results.json', function (err, data) {
    if(err){
        console.log(err)

    } else{    

    var json = JSON.parse(data)

    ...

    global.Identifier;
    global.Identifier = Identifier;
    return global.Identifier;

    } 
    }

);
res.redirect("/");
});

snippet of second post request that accesses global variable:

app.post("/addtask", function(req, res) {
    var gloablIdentifier = global.Identifier;
    ...
    res.redirect("/");
};

(When the second post request is accessed a second time, the value of gloablIdentifier = undefined )

NOTE: I understand that using global variables is VERY BAD PRACTICE and should be avoided in most situations at all costs, but I would still like to work on this problem.

Thanks in advance

bgmn
  • 498
  • 2
  • 7
  • 25
  • Seems like you want a session variable, rather than a global one. Not sure why the global doesn't work but it might be Node cleaning up between routes or a different side-effect that results in this. – VLAZ Mar 30 '20 at 11:27
  • How does your node program run? – evolutionxbox Mar 30 '20 at 11:27
  • @evolutionxbox When a user logs in, their details are identified by the Identifier variable in the first post route and the second post route is responsible for displaying the details on the screen. (I understand that this is very insecure and would lead to many privacy issues and using something like passport.js would be a lot better) – bgmn Mar 30 '20 at 11:34
  • Do you run your code in a “lambda” or other short life instance? – evolutionxbox Mar 30 '20 at 11:36
  • @evolutionxbox no, I haven't done this – bgmn Mar 30 '20 at 11:39
  • REST API's should be stateless. keeping/using the data calculated on another request is violating the same. you can return the response from first request and client needs to cache that data (if cacheable) and send the same in successive requests as per requirement. – AZ_ Mar 30 '20 at 11:41
  • @VLAZ I'm quite new to node.js and am unsure of how to change global variables into session variables. Could you help? – bgmn Mar 30 '20 at 13:00

2 Answers2

1

You did not wait readFile has to be finished and return response. Since, fs.readFile is async, global.Identifier will update later. You can await to read the file and then return;

app.post("/login", function(req, res) {
  fs.readFile("results.json", function(err, data) {
    if (err) {
      console.log(err);
    } else {
      var json = JSON.parse(data);
      global.Identifier = Identifier;
      return global.Identifier;
    }
    // wait for read file
    res.redirect("/");
  });
  // res.redirect("/");
});

async-await version:

const { promisify } = require("util");
const readFile = promisify(fs.readFile);

app.post("/login", async function(req, res) {
  try {
    const data = await readFile("results.json");
    var json = JSON.parse(data);
    global.Identifier = Identifier;
    return res.redirect("/");
  } catch (error) {
    return res.redirect("/");
  }
});
xdeepakv
  • 7,835
  • 2
  • 22
  • 32
  • This doesn't explain why the second post route works perfectly when its accessed the first time. – bgmn Mar 30 '20 at 11:48
  • Unfortunately the same error persists after implementing this solution. – bgmn Mar 30 '20 at 12:37
1

From the looks of it, you are using something like Express.

Even though this might be a bad practice I think that you should give a try to using the set functionality provided by express itself.

As such, in your app.js do it like this:

app.set("identifier", Identifier)

Then, in your routes:

app.post("/addtask", function(req, res) {
    var gloablIdentifier = app.get('identifier')
    ...
    res.redirect("/");
};

I did not test this, it's based on the documentation and on this answer

EDIT: I tested this and it works. Also, to change the variable again just do this on your route:

app.set('identifier', newValue)

I hope the answer is complete now!

Pedro Filipe
  • 995
  • 1
  • 8
  • 17