1

Hello I am fairly new to Node, express, and pug I am trying to render an object to a view and I am receiving a pug error, Or at least I think it is a pug error. I am using the pugcli and when it tries to render the html I get an error.

The pugcli error is displayed on the terminal as:

Cannot read property 'length' of undefined

This is strange because when I try to view it in the browser even though the pug cli shows an error the browser shows a list but with all the <li> elements empty.

I want the <li> to display the objects id, name,and age

I understand that in pug in order to render an object you have to iterate through it with a for loop of some kind. I have written that in the pug file but the objects do not render.

I would appreciate help about what I am missing in the code or if I completely screwed up the code somehow?

My setup is at follows

bin/www
public
   javascripts
   stylesheets
routes
   index.js
views
   index.pug
   layout.pug
   ...
app.js

My index.pug is:

extends layout
block content
  h1= title
  p Welcome to #{appHeading}
  div
    ul
      for user, i in users
        li= users.name +" - "+ users.id
      li=number

This is my index.js is:

var express = require('express');
var router = express.Router();
var users = [
  {
    id: 0,
    name: 'Glenn',
    age: 40
  },
  {
    id: 1,
    name: 'Jeff',
    age: 37
  },
  {
    id: 2,
    name: 'Sara',
    age: 22
  },
  {
    id: 3,
    name: 'Bill',
    age: 41
  },
  {
    id: 4,
    name: 'Mary',
    age: 29
  },

];
var appHeading = 'my object render app ' 
var number = 42;
/* GET home page. */
router.get('/', function(req, res, next) {

  //res.json(users);
  //res.send('Is this working?')
  res.render('index', { 
    title: 'This is my app to render objects in pug',
    users,
    number,
    appHeading
  });
});
module.exports = router;

and My app.js is:

const createError = require('http-errors');
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const logger = require('morgan');
const bodyParser = require('body-parser');

const indexRouter = require('./routes/index.js');
const usersRouter = require('./routes/users.js');

const app = express();

/*const logging = function(req, res, next){
  console.log('Logging....')
  next();
}
*/
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');

app.use(logger('dev'));
//Body Parser middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended : false}));
//app.use(express.json());
//app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
//app.use(logging);
app.use('/', indexRouter);
app.use('/users', usersRouter);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});


app.listen(port=3000 , function(){
  console.log('Server started on port '+ port);
})
module.exports = app;
6
  • Welcome to StackOverflow I hope we can help you to find the answers you look for. What is shown when you put !{JSON.stringify(users)} in your template? Commented Nov 15, 2018 at 4:20
  • @JuanD.Gómez Thank you for your help. I tried playing around json.stringify. I added !{JSON.stringify(users)} to the pug file and it created an error in the rendor or the page. It did not like that code in the pug file. I tried it in the js file and it didn't do anything. I further played with ti and it turned the object to a string. I could no longer call something like users.id and get the id. It became a complete string which I would have to parse completely. this is not going to work. I would appreciate any other help. Commented Nov 15, 2018 at 7:23
  • @Graham Thank you for your advise but I tried extending the code as you advised and it didn't do anything, I also took out the variables except users and the problem persisted. I did find out the that the error Cannot read property 'length' of undefined comes from line 9 in the index.pug the line is for user, i in users. I appreciate any help. Commented Nov 15, 2018 at 7:34
  • Are your other variables getting passed to the template? I mean, can you access the other variables you are passing in the template?. The intention of using !{JSON.stringify(users)} is to debug and check that the users array is getting passed correctly. So, you don't have to keep this code in the template just check that the values are right and then remove it. Commented Nov 15, 2018 at 13:32
  • I am voting to close this question as it was due to a small typographical error (users vs. user). Commented Nov 15, 2018 at 15:18

1 Answer 1

0

It seems that it was a typo after all:

extends layout
block content
  h1= title
  p Welcome to #{appHeading}
  div
    ul
      for user, i in users
        li= user.name +" - "+ user.id
      li=number

This will work. What happened was that you were accessing users (an array) and not user (the iterated object). I've tried the code in my machine and works just fine.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for the answer I am relatively new to this and I got confused as to which item I needed to call on. I see it much more clearly now!!!! I am grateful to the community Thank you all

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.