Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

each fails with variable named "officers" #3263

Closed
jabberwock31415 opened this issue Jun 3, 2020 · 15 comments · Fixed by #3274
Closed

each fails with variable named "officers" #3263

jabberwock31415 opened this issue Jun 3, 2020 · 15 comments · Fixed by #3274
Labels

Comments

@jabberwock31415
Copy link

Pug Version: your version number here
3.0.0

Node Version: your version number here
10.21.0

Input JavaScript Values

router.get('/foo', (req, res, next) => {
    res.render('foo', {});
});

Input Pug

- let officers = [{name:'alan'}, {name:'betty'}, {name:'charlie'}];
each dude in officers
  p #{dude.name}

Expected HTML

<p>alan</p>
<p>betty</p>
<p>charlie</p>

Actual HTML

none--pug errors out

Additional Comments

I get an error thrown from pug:

Error: /home/NPL/www/express-web/views/directory.pug:3:22
1| - let officers = [{name:'alan'}, {name:'betty'}, {name:'charlie'}];
2|

3| each dude in officers
----------------------------^
4| p #{dude.name}
5|

The value variable for each must either be a valid identifier (e.g. item) or a pair of identifiers in square brackets (e.g. [key, value]).

If I change the name of the variable from "officers" to something else ("ooficers" for example) the script works

@ForbesLindesay
Copy link
Member

Thanks for reporting this. I will look into fixing it, as it is an un-intentional regression. In the mean time, if you update to the newer syntax, that should work:

- let officers = [{name:'alan'}, {name:'betty'}, {name:'charlie'}];
each dude of officers
  p #{dude.name}

@jabberwock31415
Copy link
Author

I get the same error with the new syntax:

Error: /mnt/storage/npl/www/express-web/views/foo.pug:3:22
    1| - let officers = [{name:'alan'}, {name:'betty'}, {name:'charlie'}];
    2| 
  > 3| each dude of officers
----------------------------^
    4|   p #{dude.name}
    5| 

The value variable for each must either be a valid identifier (e.g. `item`) or a pair of identifiers in square brackets (e.g. `[key, value]`).

error418 added a commit to error418/pug that referenced this issue Jul 3, 2020
improve capture group regex for `each` statements using a greedy match.

fixes pugjs#3263
@error418
Copy link
Contributor

error418 commented Jul 3, 2020

Proposed a Pull-Request. Rename your variable to start with something other than of, in case you need a quick workaround

error418 added a commit to error418/pug that referenced this issue Jul 9, 2020
@efiand
Copy link

efiand commented Oct 31, 2020

Variable named offers gives the same error. Maybe, of sequence is a reason of this bug.

@error418
Copy link
Contributor

error418 commented Nov 1, 2020

The variable must not start with any of the keywords (like of)

@Delagen
Copy link

Delagen commented Jan 20, 2021

Half year past, breaking issue does not solved

@trasherdk
Copy link

@Delagen Seems just fine to me. Did you try?

- let officers = [{name:'alan'}, {name:'betty'}, {name:'charlie'}];

each officer in officers
  officer #{officer.name}

image

@Delagen
Copy link

Delagen commented Jan 21, 2021

Try to use via locals as express template engine

@trasherdk
Copy link

This run in the browser, no express involved, still good.

JSON:

{
  "user": {
    "name": "TrasherDK",
    "options": {"A": "Alpha","B": "Bravo","C": "Charlie","D": "Delta"}
  },
  "officegirls": [
    {"name":"Alice"},
    {"name":"Beatrice"},
    {"name":"Cindy"}
  ],

PUG:

- let officers = [{name:'alan'}, {name:'betty'}, {name:'charlie'}];
each officer in officers
  officer #{officer.name}

each officegirl in officegirls
  officer #{officegirl.name}

#select Select something &nbsp;
  select
    each option in user.options
      option(option.id) #{option}

Output:
image

image

@error418
Copy link
Contributor

error418 commented Jan 21, 2021

I think this would also fail if your variable would start with the characters "in". #3274 fixes this behaviour for the of-syntax.

/edit: I tested the regex for the in syntax. It seems to be not affected by this issue since it is not using .*. Nonetheless the bug exists for the of syntax and needs a fix.

@trasherdk
Copy link

The each of syntax does not compile on the version of PUG served from https://pugjs.org/js/pug.js

Pug:30:9
    28| #select Select something  
    29|   select
  > 30|     each option of user.options
----------------^
    31|       option(option.id) #{option}
    32|     
    33| - var name= "Bob"

malformed each

thekevinhunt added a commit to thekevinhunt/pug that referenced this issue Mar 3, 2021
I was still hitting issue pugjs#3263 when using "in" instead of "of" (which caused other odd problems).  The regex was looking for * (0+) spaces instead of + (at least one) space.  Using + instead prevents the regex from catching "in ofxxxxx".
paulwalko added a commit to ocvt/ocvt-site that referenced this issue Sep 7, 2021
@ghost
Copy link

ghost commented Oct 2, 2021

I have a same problem
code:

extends dashboardLayout

block content
    h4.grey-text.center-align Offerwalls
    .row.justify-content-center.justify-content-md-start(style="margin-top: 3rem;")
        each offerwall in offerwalls
            .col.card.shadow.border-0.m-1(style='min-width: 15rem;max-width: 18rem;')
                img.card-img-top(src=`${offerwall.bannerImgUrl || '/img/noimage.png'}` style='height:15rem;object-fit: cover;')
                .card-body
                    h6.card-title.font-weight-bold #{offerwall.title}
                    br
                    p.text-grey #{offerwall.description}
                    .text-center 
                        a.btn.btn-primary(href=`/dashboard/offerwall/${offerwall.id}`) Show #{offerwall.title}

error:

    4|     h4.grey-text.center-align Offerwalls
    5|     .row.justify-content-center.justify-content-md-start(style="margin-top: 3rem;")
  > 6|         each n in offerwalls
-----------------------------------^
    7|             .col.card.shadow.border-0.m-1(style='min-width: 15rem;max-width: 18rem;')
    8|                 img.card-img-top(src=`${offerwall.bannerImgUrl || '/img/noimage.png'}` style='height:15rem;object-fit: cover;')
    9|                 .card-body

The value variable for each must either be a valid identifier (e.g. `item`) or a pair of identifiers in square brackets (e.g. `[key, value]`).

@bglamadrid
Copy link

bglamadrid commented Jul 13, 2022

Hi, I faced this problem when I had a variable named offers that I tried to iterate over.
I see PR #3318 would address the issue but it's stalled since Jul 2021, if there's anything I can do to help get it up and working, I'm up for it!

@umnyash
Copy link

umnyash commented Oct 18, 2023

This was extremely unexpected. I spent the whole evening yesterday trying to figure out what was going on.

@efiand
Copy link

efiand commented Oct 18, 2023

I also spent a few hours then. But is it still relevant?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants