Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

How to show an error message on the browser in an Express.js app?

I have an Express.js app that takes user input, processes it, and possibly displays an error message on the browser page if a certain condition is not met. What is the recommended way to do this? I tried using a variable that is passed to the web page. For example, I do something like this:

let errorMessage;
app.get("/", (req, res) => {
    if (errorMessage) {
        res.render("home", { errorMessage });
    } else {
        res.render("home");
    }
});
app.post("/", (req, res) => {
    if (condition) {
        errorMessage = "Oops! There was something wrong with your input!";
        res.redirect("/");
    }
});

If I do it like this, will the error message variable be shared by all users? I feel like there has to be a better way. I could call res.render in the app.post callback, but then if one page has more than one form, I would need different post routes for that page. Then, the URL in the browser would change when you submitted the form. For example:

app.get("/", (req, res) => {
    // this page has multiple forms
    res.render("home");
});
app.post("/a", (req, res) => {
    // POST route for form 1
    if (condition) {
        res.render("home", { errorMessage: "Oops! There was something wrong with your input!" });
        // route is now "/a" instead of "/" and will show up in browser as "[your domain]/a" instead of just "[your domain]"
    } else {
        // route is now "/a" instead of "/" and will show up in browser as "[your domain]/a" instead of just "[your domain]"
        res.render("home");
    }
});
app.post("/b", (req, res) => {
    // POST route for form 2
    if (condition) {
        res.render("home", { errorMessage: "Oops! There was something wrong with your input!" });
        // route is now "/b" instead of "/" and will show up in browser as "[your domain]/b" instead of just "[your domain]"
    } else {
        // route is now "/b" instead of "/" and will show up in browser as "[your domain]/b" instead of just "[your domain]"
        res.render("home");
    }
});

Is this the recommended way to do it? Is there a way to avoid the URL changing?

3 Answers

Rohald van Merode
seal-mask
STAFF
.a{fill-rule:evenodd;}techdegree
Rohald van Merode
Treehouse Staff

Hi babyoscar,

I think your thinking process is correct and your solution should be working perfectly. In the POST route you'll want to make sure the condition / validation is met before redirecting the user to the next page, If not render a template showing that error (most likely the form page again, maybe set the req.body values to the inputs again so the user doesn't have to fill the entire form again).

I'm not entirely sure what you mean by will the error message variable be shared by all users. Could you please elaborate on that?

As for the multiple forms on a page question you can definitely have multiple forms on a page and then have them post to different routes. This route doesn't have to be the same as the URL in the browser. You can set this up in the form using the action attribute. Here you can define to which route the POST request has to be made.

I hope this helps and gets you going again 😄

Wouldn't there need to be a POST route with the same route as the action attribute? For example, if my action attribute is /a, then I would need a POST route with a route of /a, right? If I call res.render in that POST route, the route shown in the browser would change to /a. How can I avoid that?

What I mean by "Will the error message variable be shared by all users" is if one user causes the program to assign an error message to a variable, would that variable have that same value for all users?

Rohald van Merode
seal-mask
STAFF
.a{fill-rule:evenodd;}techdegree
Rohald van Merode
Treehouse Staff

Hi babyoscar,

You could use res.redirect to redirect the user to a different route then let that route do the rendering. With the snippet from your first post for example you can write it like so:

app.get("/", (req, res) => {
    // this page has multiple forms
    res.render("home");
});
app.post("/a", (req, res) => {
        // conditional logic
        res.redirect("/");
    }
});

This would redirect the user back to the home page which in turn triggers that first GET request and thus renders the home page.

As for the second question the variable will be set at the moment the route receives the request. This will only be rendered to that specific user.

Hope that answers your question 🙂

Do I only redirect to the GET route if there is no error? If so, how could I render the error message in the POST route without the route changing in the browser (for example from / to /a)? If not, how could I render the error message in the GET route without using variables? Or are variables the recommended way to do it?

Do you mean that the variable will have a different value for every user? For example if user 1 visits the page, and causes the program to assign the variable to "Error!", if user 2 visits the page, what would the value of the variable be? Would it be "Error!"?

Rohald van Merode
seal-mask
STAFF
.a{fill-rule:evenodd;}techdegree
Rohald van Merode
Treehouse Staff

Hey babyoscar,

It really depends on how your project is set up and how/where you want the errors to render. There's a lot of different ways to handle validation errors like this. I'd suggest to checkout the Express Basics course. Sequelize Model Validation might also be very helpful as that shows a nice way of rendering errors on the current page, not sure if you're using Sequelize or databases at all but the way errors are handled in that course can also be used in different ways.

Hope this helps