20

As described here: http://jade-lang.com/reference/, it is easy enough to either get the index or the key. But is there a way to get both?

This:

ul
  each val, index in {"day": "Wed", "link": "url", "message": "three"}
    li#item-= index + ': ' + val

Outputs this:

<ul>
  <li id="item-">day: Wed</li>
  <li id="item-">link: url</li>
  <li id="item-">message: three</li>
</ul>

But I want this:

<ul>
  <li id="item-0">day: Wed</li>
  <li id="item-1">link: url</li>
  <li id="item-2">message: three</li>
</ul>
Scott Simpson
  • 3,572
  • 3
  • 25
  • 34
  • Note that JavaScript does not guarantee the order of keys in an object. http://stackoverflow.com/questions/5525795/does-javascript-guarantee-object-property-order – sffc Aug 27 '16 at 22:09

3 Answers3

38

I think you only get an index if you are iterating over an array, so the jade documentation is a little confusing with its example. I'll give you three options for how to accomplish this. Choose your own adventure!

option 1: Keep your original input and build your own index

ul
  -var index = 0
  each val, key in {day: "Wed", link: "url", message: "three"}
    li(id="item-#{index++}") #{key}: #{val}

option 2: Change your input to an array of arrays

ul
  each val, index in [["day", "Wed"], ["link", "url"], ["message", "three"]]
    li(id="item-#{index}") #{val[0]}: #{val[1]}

option 3: Change your input to an array of objects

ul
  each val, index in [{day: "Wed"}, {link: "url"}, {message: "three"}]
    li(id="item-#{index}") #{Object.keys(val)[0]}: #{val[Object.keys(val)[0]]}

The first option is probably what you want, but the others may be interesting to read.

David Weldon
  • 59,944
  • 10
  • 136
  • 139
  • Thanks for this. It set me on the path but assigning the attribute didn't work with the `(id="item-#{index}")` syntax. This more Javascripty syntax worked for me: `(id="item-"+index)`. Perhaps a change in Jade versions/syntax since the original post? [codepen example with each example above|http://codepen.io/anon/pen/aBavMG] – Will Dec 11 '16 at 22:04
1

Just to add to this already answered question, I wasn't able to get any of these to work reliably with PyJade. I can't find the page that referred me to this tip, but it's worked perfectly for me.

Add this to your __init__.py file to added the enumerate function to your pyjade environment.

app.jinja_env.globals.update(enumerate=enumerate)

Then, you can use it in your templates like any other pythonic enumeration loop:

for idx, val in enumerate(list_of_whatevs)
    {{ idx }}, {{ val }}

Cheers

Scott
  • 2,804
  • 3
  • 29
  • 35
0

One more option using Object.entries() (and Pug 2.0.4):

ul
  each entry, index in Object.entries({day: 'Wed', link: 'url', message: 'three'})
    - const [key, val] = entry
    li(id=`item-${index}`) #{key}: #{val}
Matias Kinnunen
  • 5,463
  • 3
  • 27
  • 30