Search code examples
node.jsjsonexpresscommand-line-interfacepug

Trying to iterate over JSON in Pug but keep getting length error


I am using express and pug.

here is the index.js file :

app.get('/', function(req, res) {
    var bookStore = [
        {
            title: "Templating with Pug",
            author: "Winston Smith",
            pages: 143,
            year: 2017
        },
        {
            title: "Node.js will help",
            author: "Guy Fake",
            pages: 879,
            year: 2015
        }
    ];
    res.render("index", {
        bookStore: bookStore
    });
});

here is the pug template :

each book in bookStore
    ul
        li= book.title
        li= book.author
        li= book.pages
        li= book.year

everytime I try to use the pug cli to translate the index.pug file, I get this error:

TypeError: index.pug:1
  > 1| each book in bookStore
    2|     ul
    3|         li= book.title
    4|         li= book.author

Cannot read property 'length' of undefined
    at eval (eval at wrap (C:\Users\\AppData\Roaming\npm\node_modules\pug-cli\node_modules\pug-runtime\wrap.js:6:10), <anonymous>:6:32)
    at eval (eval at wrap (C:\Users\\AppData\Roaming\npm\node_modules\pug-cli\node_modules\pug-runtime\wrap.js:6:10), <anonymous>:53:4)
    at template (eval at wrap (C:\Users\\AppData\Roaming\npm\node_modules\pug-cli\node_modules\pug-runtime\wrap.js:6:10), <anonymous>:54:3)
    at renderFile (C:\Users\\AppData\Roaming\npm\node_modules\pug-cli\index.js:285:40)
    at C:\Users\\AppData\Roaming\npm\node_modules\pug-cli\index.js:149:5
    at Array.forEach (<anonymous>)
    at Object.<anonymous> (C:\Users\\AppData\Roaming\npm\node_modules\pug-cli\index.js:148:9)
    at Module._compile (internal/modules/cjs/loader.js:1158:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10)
    at Module.load (internal/modules/cjs/loader.js:1002:32) {
  path: 'index.pug'
}

At first I wasn't confident about my code. But this is a supposedly working example : https://pug.programmingpedia.net/en/tutorial/9545/iteration-with-pug

What am I doing wrong, it seems that since pug cli dosn't "know" the bookStore variable it won't compile... But isn't that the principle of templating ? Did I miss some declaration or something ?


Solution

  • You need to use express to do that which Getting started with pug mentioned it instead of cli.

    First, run npm install express pug to install package.

    Second, setup your server.js with following code.

    // server.js
    const express = require('express')
    const app = express()
    
    // setup template you want to use.
    app.set("view engine", "pug")
    
    app.get('/', function (req, res) {
      res.render('index', {test: [1,2,3]})
    })
    
    app.listen(8080)
    

    Third, setup your index.pug into "views/index.pug" with following content.

    div
        each val in test
            ul
                li= val
    

    Now your folder structure will look like this.

    |-- node_modules
    |-- server.js
    |-- views
    |----|---index.pug
    

    Fourth, start your server by node server.js.

    Final, type http://localhost:8080 url in browser, you'll see the result.