2

I have my application structured with 3 Routes (api, admin, default). Each lives in there own file and has it's own middleware and exports a Route. The problem I am facing is when I want to forward to another route that lives on a different router. Essentially I want to call the same function so that I am not serving up the same view from multiple locations.

I don't want to user res.redirect('/someplace') because I want to be able to pass the req and res objects on to the method.

|-app.js
|-routes
  |---admin.js
  |---api.js
  |---default.js

The routes are required and used in app.js as follows

app.use('/api', require('./routes/api')(passport);
app.use('/admin', require('./routes/admin')(passport);
app.use('/', require('./routes/default')(passport);

Inside of admin if have a situation where I need redirect to login and pass some data

// authenticates all routes for the admin router
router.use(function(req, res, next){
    if(req.isAuthenticated()){
        return next();
    }
    res.flashMessage.push('Session expired'); //is lost after redirect
    res.redirect('/login');
    //do I need to restructure my whole app so that I don't
    //have to call res.redirect('login')
});

Any ideas on how to structure this? Do I need to export every method and keep all of my routes in one router file? That doesn't very clean, but if the functions are somewhere else it may be too messy.

MondayPaper
  • 1,569
  • 1
  • 15
  • 20
  • 1
    If you want to change the URL from the server side, you're going to have to redirect them out and back in (which loses the req/res). Have you considered displaying a message on the login page based on if a URL parameter exists? Say for instance if the user navigates directly to `/login` they don't see a message, but if they are redirected there you include the original URL as a URL parameter, and if it exists, display the message. – dylants May 31 '14 at 04:15

1 Answers1

2

You can forward it by calling the next callback ,but only if you do not use any paths.

app.use(function(req, res, next) {
    // ... api
    next();
});

app.use(function(req, res, next) {
    // ... admin
    next();
});

Another option is use * that will match all paths:

app.use("*", function(req, res, next) {
    var path = req.path; // just example how it can be done

    if (path === "/api") {
       // ...
       path = "/admin";
    }

    if (path === "/admin") {
       // ...
    }
});

Edit:

I don't think that express has something like next('/login'); ,so basically function that can forward a request to another path and I don't think that is right to have something like this. If a client ask for /admin you should send this particular page and not the page that is under /login. If you want to send back to a client the login page than just redirect it as you did it in your question. I understand that you want to keep the req, res ,but then is the problem in the proposal/structure of your webapp.

0101
  • 2,697
  • 4
  • 26
  • 34
  • I saw the comment above saying I could just pass a url parameter in the redirect, is that the most common way getting a flash message to a redirect? – MondayPaper Jun 03 '14 at 19:12
  • I am not sure what you mean. If something like `/login?msg=wrongPassword` or `/login/msg/wrongPassword` then yes, it is common I would say... – 0101 Jun 03 '14 at 19:26