2

I have a pug template that should should display red text when an error is returned and green text when an operation is successful.

I have difficulty setting the <p/> classname(s) based on the status response returned from my NodeJS backend.

My NodeJS renders my page as follows:

router.get('/forgot-password',
    session.ensureNotLoggedIn('/user/dashboard'),
    (req, res, next) => {
        res.render("forgot-password");
    });

router.post('/forgot-password',
    session.ensureNotLoggedIn('/user/logout'),
    (req, res, next) => {
        if (!req.body.edtEmail) {
            res.render("forgot-password");
        }
        emailer.sendVerifyEmail().then(value => {
            res.render("forgot-password", {message: "Email sent, check your inbox!", status: true});
        }).catch(reason => {
            res.render("forgot-password", {message: "Failed to send email [" + reason + "]", status: false});
        })
    });

The key take away is the { message: [string], status: [bool] }. I need to render the message, and based on the status, the should either have a class text-danger or text-success if failed or successful respectively.

Below are various methods I have tried without success. To clarify, the status value is false which should add text-danger class.


In my pug template:

  • I have tried (source):

    p#lblMessage(class = status ? text-success : text-warning) #{message}

rendering

<p id="lblMessage">Failed to send email [true]</p>
  • Tried (source):

    p#lblMessage(class="#{status ? text-success : text-warning}") #{message}

rendering:

<p class="#{status ? text-success : text-warning}" id="lblMessage">Failed to send email [true]</p>
  • Tried (source):

    p#lblMessage(class = "#{status ? text-success : text-warning}") #{message}

rendering:

<p class="#{status ? text-success : text-warning}" id="lblMessage">Failed to send email [true]</p>

Doing something like this seems quite counter productive and ridiculous in the case of having multiple classes and states, etc (below which doesn't work ofc - most likely as I am doing something wrong: source).

if (status)
    p.text-success#lblMessage #{message}
else
    p.text-warning#lblMessage #{message}

How can I use variables passed from NodeJS backend to add/alter/remove classes of html elements in pug template?

CybeX
  • 2,060
  • 3
  • 48
  • 115

2 Answers2

3

Adding a conditional classname can be achieved by this:

p#lblMessage(class=(status  ? 'text-success' : 'text-warning')) #{message}

To explain the difference between above code and your mentioned example:

The class attribute is getting a string, pug use this as value. If a boolean is returned (or null), the attribute self gets rendered or not. E.g. a checkbox:

input(type='checkbox', checked=(1===1 ? true : false))
input(type='checkbox', checked=(1===2 ? true : false))

rendered to:

<input type="checkbox" checked="checked">
<input type="checkbox">
tom
  • 9,550
  • 6
  • 30
  • 49
1

After some testing, more reading/searching, etc I found a working solution. I do not recommend using my solution, I am posting it as a 'stepping stone' of how I cam to a solution based on my reading up on suggestions, forums, etc.

Note, I wasn't aware of the parenthesis () syntax at the point of finding a solution

//this first line is in the case of a GET, so the <p/> isn't rendered
if status !== undefined
    p#lblMessage(class=status ? "text-success" : "text-danger") #{message}

Using WebStorm, I noticed a possible syntax error (however the page compiled correctly): enter image description here

I suggest to use @kmgt's solution instead

CybeX
  • 2,060
  • 3
  • 48
  • 115