How to fix render ejs in node properly - javascript

I'm fetching data from mongodb and sending it through as res.render('user', {data: result}).
Now at ejs side I'm fetching this data field is a JSON object with name, email, password etc. field and array of attendance. Like this result:
{
name:"Joe",
password:"jdsj",
attendance:[
entry: Date,
late: true/false
]
}
Now when I loop through this array like:
<% var counter = 0 %>
<% for( var i = 0; i< data.attendance.length/2;
i+2{%>
<% if(data.attendance.length===0){%>
<% counter=0 %>
<% } else{ %>
<% counter++ %>
<% } %>
<% } %>`
When I fetch it on a page, it is not rendering. It is rendering ok without the for loop, but with looping its not rendering.
<li><%= data.name%></li>
<li><%= counter %></li>
...

You should append data in li element inside loop like this
<ul>
<% for(var i=0; i<data.length; i++) {%>
<li><%= data.name %></li>
<% } %>
</ul>

Related

EJS if else statment, array items

Im trying to render some API data using express (REST) and EJS (template engine) depending on which value "status" has. If any item in the array contains a status which is not "CLOSED" it should proceed and show those and if every item in the array has the status value set to "CLOSED" it should render a message saying "not found / no active cases"
<% for (var i=0, n=array.length; i < n; ++i){ %>
<% if (array[i].status !== "CLOSED") { %>
// This works as intendend and only renders array items without the status set to closed
<div><% array[i].status %> </div>
<% } else { %>
// This will however render this message the in the amount of array items that exists.
<div>Not found / no active cases </div>
<% } %>
How can I break out of the loop somehow and only display the message once?
The following has been tried and it works, sort of, however the message keeps looping.
<% for (var i=0, n=array.length; i < n; ++i){ %>
<% if (array[i].status !== "CLOSED") { %>
// This works as intendend and only renders array items without the status set to closed
<div><% array[i].status %> </div>
<% } else { %>
// This will however render this message the in the amount of array items that exists.
<div>Not found / no active cases </div>
<% } %>
I have also tried this, this yields the same result as the above.
<% for (var i=0, n=array.length; i < n; ++i){ %>
<% if (array[i].status !== "CLOSED") { %>
<div><% array[i].status %> </div>
<% } else if(array[i].status === "CLOSED") { %>
<div>Not found / no active cases </div>
<% } %>
<% } %>
You could filter all the elements which don't have status CLOSED, and if there are any, render them, else, show the message:
<% const notClosed = array.filter(el=> el.status !== 'CLOSED'); %>
<% if(notClosed.length > 0) {%>
<% notClosed.forEach(el=>{ %>
<div><%= el.status; %> </div>
<% }); %>
<% } else { %>
<div>Not found / no active cases </div>
<% } %>

How to place ejs in loops

People is an array of objects having firstName andlastName
<% for (var i = 0; i < people.length; i++) { %>
<%= firstName %> <%= lastName %>
<% } %>
Why end of %> is after loop { brakcet.
What is the need of ejs in end bracket of loop <% }%>

Node.js ejs - How to convert a comma string into an array in the ejs templated and loop over

I know I could convert the comma string into an array on the server side. Yet, is there also a way to convert a comma string into an array on the ejs template itself and then loop over the array and check if a certain value exists?
server.js
res.render('user', {
page: 'User',
menuId: 'user',
groupID: '0,1,10702,10802'
});
user.html
<% for(var i=0; i < groupID.length; i++) { %>
<% if (groupID[i] == '1') { %>
<span>Admin</span>
<% } %>
<% } %>
That's totally possible:
<% groupID.split(",").forEach(element => { %>
<% if (element === "1"){ %>
<span>Admin</span>
<% } %>
<% }); %>
Note: EJS Templates are still rendered on the Server-side! So it doesn't really matter if you just pass an Array from your server.js to EJS.

EJS comparison between two same strings

I try in ejs to compare two Strings which in the current situation are the same and it runs the else case. Here is the code:
<% var idf = notifications.data[i].from; %>
<% var ids = notifications.users[a].id; %>
<% if(idf == ids){ %>
<% index = a; %>
<script>alert('<%= index %>');</script>
<% break; %>
<% }else{ %>
<script>console.log('<%= idf %> - <%= ids %>');</script>
<% } %>
It logs 5d5ecfd1ad6d193de86c2264 - 5d5ecfd1ad6d193de86c2264
Use === instead of == to see if this fixes the issue, as it will prevent internal type coercion.
It might also be worth trimming the strings to see if there is any white space or padding added to them.
You could use the below code to compare two string values in ejs
<% if("some text" === "some text"){ %>
<h1>Yes the above text are equal</h1>
<% } %>
If you are comparing mongoDB objectId, then use toString().
<% var idf = notifications.data[i].from; %>
<% var ids = notifications.users[a].id; %>
<% if(idf.toString() == ids.toString()){ %>
<% index = a; %>
<script>alert('<%= index %>');</script>
<% break; %>
<% }else{ %>
<script>console.log('<%= idf %> - <%= ids %>');</script>
<% } %>

How to handle callback responses in Ejs

In my Node.js application I want to call some async function in Ejs code and render the result. I tried:
<ul>
<% setTimeout(function () { %>
<% supplies = [1, 2, 3, 4]; %>
<% for(var i=0; i<supplies.length; i++) {%>
<li><%= supplies[i] %></li>
<% } %>
<% }, 1000) %>
</ul>
But it seems it doesn't work. Why doesn't it work and how I can fix it?
Ok, so it seems that Ejs doesn't support such a feature, but what we can do is to deasync the function using the deasync module.
<% function foo (timeout, callback) { %>
<% setTimeout(function () { %>
<% callback(null, [1, 2, 3, 4]; %>
<% }, timeout); %>
<% } %>
<% var Deasync = require("deasync") %>
<% var fooSync = Deasync(foo) %>
<ul>
<% supplies = fooSync(1000); %>
<% for(var i=0; i<supplies.length; i++) {%>
<li><%= supplies[i] %></li>
<% } %>
<% }, 1000) %>
</ul>

Categories