How to place ejs in loops - javascript

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 <% }%>

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>
<% } %>

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 fix render ejs in node properly

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>

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>

How stop a looping in the fourty loop

I'm pulling data from my database, and sending for my views through my controllers. The date is coming, and I'm rendering this data in the HTML with a looping.
The problem is that I want to show only 4 items, not all. How can I solve this?
For example:
<% for(var i = 0; i < data.length; i++ { %>
<p> <%= data[i].name %>
<p> <%= data[i].age %>
<% } %>
I want only render 4 times. How achieve this?
Thanks!
Like this:
<% for(var i = 0; i < data.length && i<4; i++ { %>
<p> <%= data[i].name %>
<p> <%= data[i].age %>
<% } %>
I would do something like:
<% for(var i = 0,max = (data.length > 4 ? 4 : data.length); i < max; i++ { %>
<p> <%= data[i].name %>
<p> <%= data[i].age %>
<% } %>
What this does is iterate the loop either 4 times or the length of data (whichever is shorter). If you don't have that conditional, you might get into an index out of bounds (if data.length is 2, for example).
Coding note: its good practice to declare max at the beginning of the for-loop. Its more readable and, for performance sakes, the lookup of the length attribute of data only happens once (instead of each iteration).
Update based on comments
To add other conditionals (such as if the pageName = 'home')
<% for(var i = 0,max = ( (data.length > 4 && pageName === 'home') ? 4 : data.length); i < max; i++ { %>
<p> <%= data[i].name %>
<p> <%= data[i].age %>
<% } %>

Categories