title: Iteration with Pug over an object
body: <p>Passing an object to Pug from app.js</p>
  
  <pre><code>router.get('/', getMenuList, function (req, res, next) {
      res.render('menu_items', {
        title: 'The Weekly Menu',
        message: 'The List',
        dataset
    });
  });
  </code></pre>
  
  <p>The dataset looks like </p>
  
  <pre><code>menu_date   dish_name         Display
  2018-10-01  Fish              2018-10-01: Fish
  2018-10-01  Green Beans       2018-10-01: Green Beans with Mushrooms and cream
  2018-10-02  Out To Dinner     2018-10-02: Out To Dinner
  2018-10-03  Oysters           2018-10-03: Oysters an the half shell
  2018-10-03  Sauce Mignette    2018-10-03: Sauce Mignette
  </code></pre>
  
  <p>What I want to display on HTML is a nested list like</p>
  
  <pre><code>2018-10-01
         Fish
         Green Beans
  2018-10-02
         Out to diner
  2018-10-03
         Oysters
         Sauce Mignette
  </code></pre>
  
  <p>My PUG code as follows iterates over the object but I don't know how to get nested list</p>
  
  <pre><code>extends layout
  
  block content
      h2= title
      -var wtf = dataset.length
      -var n = 0
      h1= message
      each item in dataset
          ul
              li #{item.Menu_Date}
  </code></pre>
  
  <p>Posted below is the app.js which writes an html page. The code is ugly. Not facile with javascript, html nor CSS. </p>
  
  <pre><code>//submit
  var express = require('express');  
  var bodyParser = require('body-parser');  
  var app = express();  
  app.use(bodyParser.json());
  var tedious = require('tedious');
  var Promise = require('promise');
  app.use(bodyParser.urlencoded({ extended: false }));
  var path = require('path');
  var fs = require('fs');  
  
  
  
  var router = express.Router();
  var menu_data = [];    
  var menu = [];
  
  app.engine('pug', require('pug').__express);
  app.set('views', path.join(__dirname, 'views'));  
  app.set('view engine', 'pug');
  
  app.use(router);  
  app.use(express.static(path.join(__dirname, 'public')));
  
  
  
  
  
  
  
  
  router.get('/', getMenuList, function (req, res, next) {
  
  
       var item = [];
       for(var row of menu_data ){
         if(menu.length == 0) {
           var newItem = {Date: row.MenuDate, Items: item};
  
           menu.push(newItem);
  
  
  
         }
         if(row.MenuDate != menu[menu.length -1].Date) {
  
          item = [];
  
           var newItem = {Date: row.MenuDate, Items: item};
           menu.push(newItem);
  
  
         }
         var newDish = {Dish: row.Item};
  
         menu[menu.length -1].Items.push(row.Item);
        /* var i = 0;
         while(i &lt; menu[menu.length -1].Items.length) {
           console.log( menu[menu.length -1].Items[i]);
           i++;
         }
         */
  
  
  
  
  
  
       }
  
       fs.writeFileSync('./views/message.html', '&lt;!DOCTYPE html&gt;&lt;html&gt;&lt;head&gt;&lt;title&gt;The Weekly Menu&lt;/title&gt;&lt;link rel="stylesheet" href="/stylesheets/style.css"&gt;&lt;/head&gt;&lt;body&gt;', 'utf8', function(err){
        if (err) throw err;
       });
       fs.appendFileSync('./views/message.html', '&lt;h1&gt;Why the drama&lt;/h1&gt;', function(err){
         if (err) throw err;
       });
      for(index = 0; index &lt; menu.length ; index++ ) {
          //console.log(menu[index].Date);
          if(index ===0){
            fs.appendFileSync('./views/message.html', '\r\n&lt;ul&gt;', function(err){
              if(err) throw err;
            });
          }
          fs.appendFileSync('./views/message.html', '\r\n&lt;li&gt;'  + menu[index].Date + '&lt;/li&gt;', function(err){
            if(err) throw err;
          });
  
              for(newindex = 0; newindex &lt; menu[index].Items.length; newindex++) {
                  //console.log(menu[index].Items[newindex])
                  if(newindex === 0 ){
                  fs.appendFileSync('./views/message.html','\r\n&lt;ul&gt;', function(err){
                    if(err) throw err;
                    });
                  }
                  fs.appendFileSync('./views/message.html', '\r\n&lt;li&gt; ' + menu[index].Items[newindex] + '&lt;/li&gt;', function(err){
                    if(err) throw err;
                    });
                }
                fs.appendFileSync('./views/message.html', '\r\n&lt;/ul', function(err){
                  if(err) throw err;
                });
        }  // end of outer loop
  
        fs.appendFileSync('./views/message.html', '\r\n&lt;/ul&gt;\r\n\&lt;a href=\"http://localhost:3030/index\"&gt; Input Menu Items&lt;/a&gt;\r\n&lt;/body&gt;\r\n&lt;/html&gt;', function(err){
          if(err) throw err;
        });
  
     /* res.render('menu_items', {
        title: 'The Weekly Menu',
        message: 'The List',
        menu_data,
        menu
  
    }); */
  
     res.sendfile('./views/message.html');
  });
  
  router.get('/index', function(req, res) {
      res.render('index')
  });
  
  router.post('/update',submitMenuItem, function (req, res) {  
        var menu_data = req.body.menuDate;
        var description = req.body.theItem;
  
  
      res.render('update', {
          title: 'All Quiet on the Western Front',
          menuDate: menu_data,
          MenuItem: description 
  
  
      });
  
  });
  
  
   // end of submitMenuItem
  
  
  function getMenuList( req, res, next) {
      var promise = new Promise(function(fulfill, reject){
  
  
  
  
  
  
  
  
      var Connection = require('tedious').Connection;
      var Request = require('tedious').Request;
  
  
      var config = JSON.parse(fs.readFileSync('./config/config.json', 'utf8'));
  
  
      var connection = new Connection(config);
  
  
  
      connection.on('connect', function (err) {
              if (err) {
                console.log(err);
           } else {
                executeStatement();
           }
      });
     /* function MenuItem(Menu_Date, Name, Display)
      {
          this.Menu_Data = Menu_Date;
          this.Name = Name;
        this.Display = Display;
  
  
      }  */
  
      function executeStatement() {
  
           var sql = "select dt_ofItem ,dish_name  FROM LA_COUNTY.dbo.mn_items order by dt_ofItem"; 
  
           var Request = require('tedious').Request;
           request = new Request(sql, function (err, rowCount) {
                if (err) {
                     reject(err);
                } else {
                    if(rowCount &lt; 1) {
                        callback(null, false);
                    }
                    else {
                     fulfill(menu_data);
                    }
                }
           });
  
  
           request.on('row', function (columns) {
               var Menu_Date = ""
  
  
                columns.forEach(function (column) {
  
                    if(column.metadata.colName=== "dt_ofItem"){
  
                        Menu_Date = column.value.toDateString();
  
                     }
                    if(column.metadata.colName==="dish_name") {
                        //console.log(column.value);
                        //console.log('WTF');
                    //var item = new MenuItem(Menu_Date, column.value, Menu_Date + ": " + column.value);
                    var menu_stuff = {
                      MenuDate: Menu_Date,
                      Item: column.value
  
                  };
                    menu_data.push(menu_stuff);
                        //menu_data.push("Date" Menu_Date ,"Item" column.value );
  
                        //item = null;
                    }
                });
  
  
  
  
  
  
           });
  
  
           request.on('doneProc', function (rowCount, more, returnStatus, rows) {
                next(null, rows);
                connection.close()
  
  
  
  
  
               // console.log(menu_data[0].MenuDate);
  
  
                menu_data = [];
  
           });
  
           connection.execSql(request);
      }
      });
  }  // end getclients
  
  
  
  function submitMenuItem( req, res, next) {
  
  
  var menu_date = req.body.menuDate;
  var description = req.body.theItem;
  
  var Connection = require('tedious').Connection;
  
  var config = JSON.parse(fs.readFileSync('./config/config.json', 'utf8'));
  
   var connection = new Connection(config);
  
    var connection = new Connection(config);
  
    connection.on('connect', function(err) {
  
        executeStatement();
      });
  
  
  
  
  
    function executeStatement() {
      var sql = "insert LA_County.dbo.mn_items (dt_ofItem, dish_name) values ('" + menu_date + "','" + description + "')"
      var Request = require('tedious').Request;
      request = new Request(sql, function(err, rowCount) {
        if (err) {
          reject(err);
        } else {
          if(rowCount &lt; 1) {
              callback (null, false);
        }
        else {
            fulfill(menu_date);
        }
      }
      });
  
  
      request.on('row', function(columns) {
        columns.forEach(function(column) {
          //console.log(column.value);
        });
      });
  
      request.on('doneProc', function (rowCount, more, returnStatus, rows) {
          next(null, rows);
  
              connection.close()
  
  
  
           });  
  
  
  
      connection.execSql(request);
    }    
  
  } // end of submitMenuItem
  </code></pre>
  
  <p>here is the PUG code. Which I am very very unsure about</p>
  
  <pre><code>extends layout
  
  block content
      h2= title
      -var wtf = menu_data.length
      //h1 #{wtf}
      -var n = 0
      h1= message
      ul
          while n &lt; wtf
              li= menu_data[n++].MenuDate
  
  
  
      ul
          each entry in menu
              li= entry.Date
              -var i = entry.Items.length
              h3 #{i}
              -var q = 0
              ul
                  each dish in entry.Items
                      li dish
                  //while q &lt;  i
                      //li= entry.Items[q]
  
  
      a(href='http://localhost:3030/index') Input Menu Items
  
  
  
  
  
      app.listen(3030);  
      module.exports = app;  
  </code></pre>
  
  <p>For a more complete view the <a href="https://github.com/FredaDant/Menus" rel="nofollow noreferrer">code is on GIT</a></p>
  
  <p>Sorry if I am not doing these posts according to Hoyle.</p>