Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the proper way to loop through an array in an EJS template after an AJAX Call (using ExpressJS)?

I am trying to loop through an array of objects that I got from an http call using to my internal API using the request module/package. So far, I am able to get my data back from the API and DISPLAY the full object on my page. I would like to display it on my page and loop through it using the EJS templating system. I know I can use AngularJS for frontend stuff, but I would like to see how far I can go with only server-side.

Below is my code:

server.js

// Prepend /api to my apiRoutes
app.use('/api', require('./app/api'));

api.js

var Report = require('./models/report');
var express  = require('express');
var apiRoutes = express.Router();

apiRoutes.route('/reports', isLoggedIn)  
     .get(function (req, res,next) {
          // use mongoose to get all reports in the database
          Report.find(function (err, reports) {
                 // if there is an error retrieving, send the error.
                 // nothing after res.send(err) will execute
                 if (err)
                    return res.send(err);
                    res.json(reports);
          });
    });

routes.js

var User = require('./models/user');
var request = require('request');
module.exports = function (app, passport) {
    
    app.get('/reports', isLoggedIn, function (req, res) {
        res.render('pages/new-report.ejs', {
            user: req.user,
            title:'New Report'
        });
    });


    request({
        uri:'http://localhost:2016/api/reports',
        method:'GET'
    }).on('data',function(data){
        console.log('decoded chunk:' + data)
    }).on('response',function(resp){
        resp.on('data', function(data){
            console.log('received:' + data.length + ' bytes of compressed data');
            app.get('/timeline', isLoggedIn, function (req, res) {
                res.render('pages/timeline', {
                    user: req.user,
                    title:'Timeline',
                    reports: data
                });
            });
        })
    }); 
}  

reports.ejs
So if I simply output the entire reports object like this <p><%= reports %></p> on my page, everything works fine and I get something like this:

[
  {
    "_id": "5775d396077082280df0fbb1",
    "author": "57582911a2761f9c77f15528",
    "dateTime": "30 June 2016 - 07:18 PM",
    "picture": "",
    "description": "",
    "location": [
      -122.46596999999997,
      37.784495
    ],
    "latitude": 37.784495,
    "longitude": -122.46596999999997,
    "address": "4529 California St, San Francisco, CA 94118, USA",
    "contact": "John Doe",
    "type": "Financial",
    "__v": 0,
    "updated_at": "2016-07-01T02:21:10.259Z",
    "created_at": "2016-07-01T02:21:10.237Z",
    "tags": [
      "tag1,tag2"
    ]
  }
]

But if I try to loop through the object as seen below It get an UNDEFINED as a return property of my report object and I get an infinite loop apparently.

<ul class="timeline">
    <% reports.forEach(function(report) { %>
    <li class="timeline-yellow">
        <div class="timeline-time">
            <span class="date" style="text-align:left">
            <%= report.type %> </span>
            <span class="time" style="font-weight:700;font-size:25px;line-height:20px;text-align:left;">
            <%= report.dateTime %> </span>
        </div>
    </li>
    <% }) %>
</ul>

I have tried another variation of the loop but I am still unsuccessful:

<ul class="timeline">
    <% for (var i = 0; i < reports.length; i++) { %>
    <li class="timeline-yellow">
        <div class="timeline-time">
            <span class="date" style="text-align:left">
            <%= report[i].type %>
            4/10/13 </span>
            <span class="time" style="font-weight:700;font-size:25px;line-height:20px;text-align:left;">
            <%= report[i].dateTime %> </span>
        </div>
    </li>
    <% } %>
</ul>
like image 908
AllJs Avatar asked Jul 04 '16 07:07

AllJs


People also ask

What would you use to loop over data in EJS?

We use forEach on the array to start a loop and enclose the entire opening in – . The template engine begins the loop and will include the next line, outside of any EJS tags, once for each element in the array, thereby adding 3 li s to our final HTML.

How do you loop through each element in an array?

How to Loop Through an Array with a forEach Loop in JavaScript. The array method forEach() loop's through any array, executing a provided function once for each array element in ascending index order. This function is known as a callback function.

How do I use EJS templating?

Steps to run the program:After creating all the files go to the root directory of your project folder. Run command prompt in this directory. Type node file_name. js command to run your program and see the output as displayed.


2 Answers

The syntax for the for loop in ejs is perfect but the iterated array name is reports and you seem to use report[i] inside the iteration, which needs to be changed as reports[i], which should work.

reports.ejs

<ul class="timeline">
    <% for (var i = 0; i < reports.length; i++) { %>
    <li class="timeline-yellow">
        <div class="timeline-time">
            <span class="date" style="text-align:left">
            <%= reports[i].type %>
            4/10/13 </span>
            <span class="time" style="font-weight:700;font-size:25px;line-height:20px;text-align:left;">
            <%= reports[i].dateTime %> </span>
        </div>
    </li>
    <% } %>
</ul>

Hope this helps.

like image 56
SUNDARRAJAN K Avatar answered Oct 19 '22 02:10

SUNDARRAJAN K


I guess something like this .. 

<% if (reports.length > 0){%> // Checking if there are reports
  <ul class="timeline">
      <%  for (let report of reports){ %>
        <li class="timeline-yellow">
          <div class="timeline-time">
            <span class="date" style="text-align:left">
              <%= report.type %> 
               4/10/13 </span>
              <span class="time" style="font-weight:700;font-size:25px;line- 
  height:20px;text-align:left;">
              <%= report.dateTime %> </span>
          </div>
      </li>
      <% } %>
  </ul>
 <%}%>
<%}%>
like image 27
Darina Sergeivna Avatar answered Oct 19 '22 00:10

Darina Sergeivna