mde/ejs

global scope of variables

Valeri-afk opened this issue · 1 comments

Hello, im newbie in ejs, so i need a help with find out some thing.
What if i have data that i send to my ejs layout.

app.get("/", function (req, res) {
  res.render(path.join(__dirname, "./view/pages", "view.ejs"), {
    genres: [{ genre: "Adventure" }, { genre: "Fantasy" }],
    listOfMovies: [
      { title: "1", id: 1 },
      { title: "2", id: 2 },
   ],
  });
}); 

below my header has access for all my data that i sent before. But what if i need my header will have access only for genres data and not for listOfMovies data. The reason why i am asking is because I'm used to the fact that you can't use global variables. I would say that isnt global variables but anyway for me it looks like not so good when my header has aceess to all data that i pass.

<body>
    <%- include('../partials/header.ejs') %>
    <div class="background">
    </div>
    <div class="side-panel_background"></div>
    <div class="side-panel"></div>
    <button id="sendRequest">send</button>
</body>

Hello, you probably have already found a solution for this problem, but since there isn't much documentation on ejs, I will just write this to help people new to ejs.

But what if i need my header will have access only for genres data and not for listOfMovies data.

I'm not really sure if this is a question or a statement, but in your code you don't pass anything to header.ejs, so that file has no idea of neither genres nor listOfMovies. If you want to pass it to the header, I will explain that below.

for me it looks like not so good when my header has aceess to all data that i pass

That indeed, would not be good and as I just mentioned, this is not the case. As long you don't pass any data to the templates, they don't know anything.

In your example, you render the view with genres and listOfMovies as data. The important thing here is that you render that template, meaning the template engine will check through the file and put the value of the data anywhere its name is called. For example:

main.js

/* You can declare where ejs will find the views folder,
so you don't need to always use the absolute path to render pages.
(I think ejs also automatically looks if it can find a views folder in the root directory,
which results in the same outcome, but I'm not sure)*/

app.set("views", path.join(__dirname, "views"));

app.get("/", function (req, res) {

  res.render(path.join("pages/view.js"), {
    genres: ["Adventure", genre: "Fantasy"]
  });
}); 

view.js

<body>
    <%- include('../partials/header.ejs') %>
    <% for(let genre of genres) { %>
      <%= genre %>
    <% } %>
    <div class="background"></div>
    <div...
</body>
<script> ... </script>

In main.js, we pass genres to view.ejs, which will render the page, fill out any genres variables in ejs tags and then send the resulting html to the client. The only time in view.ejs the genres variable gets rendered, is in the for loop. The header will not have the genres variable, neither the html file that gets sent to the user and neither the javascript in the <script> tags.

If you want a partial to also be able to access any variable you pass to a page, you need to pass it on in the include expression like:
<%- include('../partials/header.ejs', {name_of_variable_in_partial: genres}) %>
and then you can also access it in header.ejs

header.ejs

<div class="container">
  <% if(name_of_variable_in_partial) {
         for(let genre of name_of_variable_in_partial) {%>
           <%= genre %>
  <% }} %>
</div>