0

I just want to know if there is a way to replicate this PHP code in EJS view:

<?php
  // ...
  if ($something) {
    echo 'something is true';
    die;
  }
  // Now I can continue with my code without being in "else" clause.

I feel like there is really simple solution to this but I just can't seem to find it.

Thanks in advance.

Histmy
  • 13
  • 1
  • 2
  • 1
    Do you have some EJS code you want to use with this technique? – evolutionxbox Feb 23 '21 at 22:36
  • @evolutionxbox I would like to do something very similar to the PHP example. When `id` variable is not set, I want to say something like "You need to provide ID.", import ending html and exit. Otherwise I want to continue with other code execution without needing to be indented in "else" clause. I just don't like it. – Histmy Feb 23 '21 at 22:45
  • 1
    You can create a separate function to call when the id is not set. It's good practice anyway to group your code into functions. – Kokodoko Feb 23 '21 at 22:46
  • @Kokodoko I don't understand what you mean. I am trying to avoid any "unnecessary" indentation and with this I would be indented in the function. Maybe it is just bad habit of mine, but I just don't like it. The main purpose of this site is to give some info about some article in database and when user doesn't provide id it is just meant inform them about it and simply end execution. Seperte function seems like more Haramul than good. I am sorry if I didn't explain it well. – Histmy Feb 23 '21 at 23:11
  • You explain it well :) But your motivation comes from PHP and is maybe not so applicable in Javascript. In Javascript it's good practice to put code into functions and use indentations. It just helps readability - especially since there is no `die()` which stops execution. I agree that lots of code inside an `if else` is ugly, so that's why I'd suggest a function. – Kokodoko Feb 25 '21 at 09:59
  • I tend to use a similar pattern, but inside functions. It's called early returning https://stackoverflow.com/questions/3330193/early-exit-from-function – evolutionxbox Feb 25 '21 at 10:34
  • @evolutionxbox I am not sure if you meant the label, but that can be used pretty well in my case. I just surround whole document in `a` label and when I want to `exit` I just break out of the label. Thx. – Histmy Feb 26 '21 at 14:50
  • I didn't mean the label, but I suppose you could use a labelled block. I was meaning use a function and return early inside that function. – evolutionxbox Feb 26 '21 at 14:51

3 Answers3

0

There is no JavaScript, hence no EJS equivalent, to PHP's exit() or its alias die(). The purpose of both of these PHP functions from the PHP docs:

Output a message and terminate the current script

There is no way to "terminate the current script" in JavaScript. JavaScript always runs to completion with no way to prevent that.

One alternative method of achieving your goal would be to use include and the filename option or, use renderFile() to render this template.

<% if (!something) { %>
   <%- include('/notSomethingContent'); %>
<% } else { %>
   <%- include('/somethingContent', {something: something}); %>
<% } %>

This would allow you to avoid long indented template content within the else that you "just don't like". :-)

Randy Casburn
  • 13,840
  • 1
  • 16
  • 31
0

Not really sure if this is a good idea, but the closest you can come to the desired syntax in JavaScript is using a labelled block:

myLabel: if(true) {
  console.log('before break');
  break myLabel;
  console.log('after break');
}

Running the example, you can see that "before break" logs, but "after break" does not.

Please note that I do not condone this pattern, and that the break will not affect any code outside the labelled block.

evolutionxbox
  • 3,932
  • 6
  • 34
  • 51
0

This is undocumented, but EJS just compiles your template to a JS function that returns the rendered content. It adds a variable called __output that contains the current output so far. See the EJS source here: https://github.com/mde/ejs/blob/820855ad75034e303be82c482c5eb8c6616da5c5/lib/ejs.js#L589

So, if you are fine with relying on these two undocumented behaviors (__output and EJS compiling to a function), you can simply use return __output; as a die();.

This:

one
<% return __output; %>
two

Will only render one.

To only rely on the first undocumented behavior, you can throw a special exception in the template that is then caught by the render function. You still need __output though since there is otherwise no way to obtain the partially-generated output. Something like this:

class StopEJSError extends Error {};
const die = (output) => {
  const err = new StopEJSError();
  err._output = output;
  throw err;
};
ejs.renderFile("template.ejs", {die}, (err, out) => {
  if (err instanceof StopEJSError) {
    res.send(err.output);
  } else if (err) {
    throw err;
  } else res.send(out);
});
kuilin
  • 119
  • 1
  • 7