yukashima huksay
yukashima huksay

Reputation: 6238

node.js - How to pass data from controller to middleware in expressjs?

I have an electron app I need to serve files from a certain directory. but the address if that directory is only discovered in runtime. So I've made this middleware:

app.use("/vids", (req, res, next) => {
  return express.static(the_root)(req, res, next);
});

Here is the part of my controller that discovers the root.

exports.joe = (req, res) => {
  const {dialog} = require("electron");
  dialog.showOpenDialog(
    {
      filters: [
        {name: "Anchor", extensions: ["anchor"]},
        {name: "All Files", extensions: ["*"]},
      ],
      properties: ["openFile"],
    },
    (loc) => {
      fs.writeFile(locfile, loc, function(err) {
        if (err) {
          return console.log(err);
        }
        console.log("The new root location saved: " + loc);
      });
      res.redirect("/pie");
    },
  );
};
exports.pie = (req, res) => {
    res.render('91')
}

And then in 91 template I has:

<img src="image.png">

The User is gonna select the path: /mnt/dir/ And the file is located at /mnt/dir/image.png

I would like to be able to pass the /mnt/dir/ address to the middleware in some way so that when the request is made to retrieve the image the middleware knows where to look at. How is it possible? I was thinking of putting the data in the request object somehow but I don't know how.

Upvotes: 0

Views: 1436

Answers (1)

jfriend00
jfriend00

Reputation: 707326

Given the general architecture of Express, this feels like an app configuration option that would be a natural for app.get() and app.set().

Add app.set() to save this configuration on the app object:

exports.joe = (req, res) => {
  const {dialog} = require("electron");
  dialog.showOpenDialog(
    {
      filters: [
        {name: "Anchor", extensions: ["anchor"]},
        {name: "All Files", extensions: ["*"]},
      ],
      properties: ["openFile"],
    },
    (loc) => {
      fs.writeFile(locfile, loc, function(err) {
        if (err) {
          return console.log(err);
        }

        // save this on the app object as a configuration
        req.app.set("imageDir", loc);

        console.log("The new root location saved: " + loc);
      });
      res.redirect("/pie");
    },
  );
};

Then, in your middleware, you can retrieve that at any time:

app.use("/vids", (req, res, next) => {
  return express.static(app.get("imageDir"))(req, res, next);
});

This also assumes that app.set("imageDir", ...) is called at startup to set it to some functional value.


There are numerous other ways to do this.

  1. You could set or modify an environment variable in process.env and then retrieve it from there when needed.
  2. You could save the directory as a module local and then export a function that would return the current value of that variable at any time.
  3. You could make an early stage middleware that would set the directory as a custom property on the req object so all follow-on middleware could access it. It sounds like this was perhaps your first thought at how to do it. It's not my favorite because it's really just a configuration option so it seems more natural to handle it like other configuration options with app.get() or the above two options.
  4. You could set a global property, global.imageDir that can be accessed from anywhere.

FYI, it looks like your showOpenDialog() code is missing a check for the dialog being cancelled.

Upvotes: 1

Related Questions