11

RESTful routes js file:

// index route - show all todos
router.get("/", middleware.isLoggedIn,function(req,res) {
  Todo.find({ "author.id" : req.user._id}, function(err, allTodos) {
    if(err) {
      console.log(err);
    } else {
      res.render("todo/index", {todos: allTodos});
    }
  });        
});

My index.ejs file has:

<script src="/scripts/todoCalendar.js"></script>

at the end of the body tag and I want to access the passed variable todos inside my todoCalendar.js file. I tried putting

<script>
  var x= <%= todos %>
</script>

but it says x is undefined when i try to do a console.log(x) inside my todoCalendar.js file.

Any help is greatly appreciated.

1
  • is todos ejs variable having the data you can debug using <%=todos | json> Commented Oct 3, 2017 at 7:21

5 Answers 5

28

Three way to solve the problem...

  1. variant

    <script>
        var x = "<%= todos %>";
        console.log(x); 
    </script>
    
  2. variant

    <script>
        var x = "<%- todos %>";
        console.log(x); 
    </script>
    
  3. variant [XD]

    HTML:

    <p id="yy" style="display:none"><%= todos %></p>
    

    Javascript:

    <script>
        var x = document.getElementById("yy").innerText;
        console.log(x); 
    </script>
    
Sign up to request clarification or add additional context in comments.

5 Comments

It doesn't work for me! Error Uncaught TypeError: Cannot read property 'innerText' of null
Declaring an array like this won't work. Please guide
Prathamesh, try using innnerHTML
I have a very similar case and method 3 seems to render the variable well, but I need the variable to be accessed via method 1 or 2 so I can access the variable inside the tag... my dismay, am getting Uncaught SyntaxError: Invalid or unexpected token in my browser console. NB: The variable I need contains an array of objects.
I'm passing an object to the script. To get it to work I adapted #2, using JSON.stringify() on the object when passing it to the template, and then using backticks on the variable and the more-dangerous unescaping tags <%- : let x = JSON.parse(`<%- myObject %>`);
16

By formatting the html printing of the JSON you get from the server and using javascript (my case jQuery) to retrieve that text, store it, and remove it from the html :)

EJS:

<span id='variableJSON' hidden>
    <%= JSON.stringify(passedInEjsVariable); %>
</span>

JavaScript:

var variableJSON = JSON.parse($('#variableJSON').text());
$('#variableJSON').remove();

2 Comments

This is a highly underrated answer.
Nice Hack! This should be the accepted answer, the currently highest rated answer doesn't work for objects.
4

Only this works in my case. All versions with "" or with <%= fail.

<script>
  var todos = <%-JSON.stringify(todos)%>;
  for (var item of todos) {
    console.log(item)
  }
</script>

Thing to note: if using VS Code with formatting on save for .ejs files, <%- gets split into <% - and you get Uncaught SyntaxError: Unexpected token ';' and what worked a second ago, suddenly stops working.

Comments

1

http://ejs.co/ says

  1. <% 'Scriptlet' tag, for control-flow, no output
  2. <%= Outputs the value into the template (HTML escaped)
  3. <%- Outputs the unescaped value into the template
  4. <%# Comment tag, no execution, no output

Can you try using <%- in ejs to read variable value?

4 Comments

I have tried both <%= and <%- inside the <script> tag and they do not work. Console says "invalid or unexpected token". For some reason, the <%- syntax is not doing anything inside my script tag. Granted, when I look at the source code (Ctrl + u) I can see the todos printed out i.e. var x = {obj} when I use either <%- or <%=.
res.locals.todo = JSON.stringify(object);
res.render("test",{ 'todos': JSON.stringify({a:1}) }); and then <script> var x= <%- todos %> </script>
I prefer to stringify within the ejs as opposed to the router, in order to keep my objects accessible within the view. You might want to work with object properties and if you have already stringified it that's a problem. So within the ejs <script> tags just do: var x= <%- JSON.stringify(todos) %>;
1

I am afraid you can't use EJS tags inside a file with a .js extension.

If you put the js code at the bottom of the EJS document, there is no problem.

In the backend you do:

res.render('todo/index', {todos: JSON.stringify(alltodos)}); 

In your ejs file you do:

<script>
 var x= <%- todos %>;
 console.log(x);
</script>

This works fine. I ve just tested for my project.

If you want to use the same code inside a separate file with .js extension, it will not work. You get an 'unexpected token <' error in the browser console.

The only option you have is to print todos into a hidden DIV inside the ejs file and then get in through javascript (you can use innerText or innerHTML) and store it inside a variable. A bit hacky but it does the trick.

1 Comment

This can be done in a tricky way by enclosing a .js file content inside <script> tags, saving it as an .ejs file and using the <%- include('jsfile'); %> directive inside the html .ejs file and using <%- template tags in it as described above.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.