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

Parent context wrong for first each iteration #1831

Open
ulriklystbaek opened this issue Feb 21, 2022 · 4 comments
Open

Parent context wrong for first each iteration #1831

ulriklystbaek opened this issue Feb 21, 2022 · 4 comments

Comments

@ulriklystbaek
Copy link

ulriklystbaek commented Feb 21, 2022

Can easily be re-produced using http://tryhandlebarsjs.com/

Context: ["hallo", "fisk"]
Template:
{{#with this.[0]}}
{{#each @root}}{{../this}}{{/each}}
{{/with}}

Handlebars 4.0.3 (wrong): hallo,fiskhallo
Older versions returns correctly: hallohallo

@jaylinski
Copy link
Member

jaylinski commented May 25, 2022

It doesn't make sense to use @root and ../this. If you are at the root, you don't have any parent context. Or am I missing something?

It is a bug, but it seems like an edge-case.

@jaylinski jaylinski added the bug label May 25, 2022
@PitPik
Copy link

PitPik commented Jun 19, 2022

@jaylinski It seems like an edge-case when you use @root or let the context be just a simple Array, but the problem is not about this scope but the data inside the context (also, the headline of this issue mentions the 1st iteration, but it's not the iteration but the content, so it could also be the 2nd).
It might be related to the issue #1762 (as this bug is very tricky as well and has to do with content of Objects/Arrays).
So, given the following scenario:

var context = {
    elementsArray: ["H", "O2"],
    elementsArray2: ["H", "O2:"],
    elementsArray3: ["H:", "O2"],
    elements: {
        hydrogen: 'H',
        carbonDioxide: 'O2'
    }
};
var template = `
   {{#with elements.hydrogen}} {{!-- Also try #with elementsArray.[0], same wrong outcome --}}
      {{!-- Test 1: Doesn't work --}}
      {{#each ../elements}} Combine {{../this}} with {{.}};<br>{{/each}}<br>

      {{!-- Test 2: Doesn't work --}}
      {{#each ../elementsArray}} Combine {{../this}} with {{.}};<br>{{/each}}<br>

      {{!-- Test 3: Doesn't work --}}
      {{#each ../elementsArray2}} Combine {{../this}} with {{.}};<br>{{/each}}<br>

      {{!-- Test 4: Works --}}
      {{#each ../elementsArray3}} Combine {{../this}} with {{.}};<br>{{/each}}<br>
  {{/with}}
`;

Test 1, 2 and 3 are failing because of the content of the 1st element of the Object or Array is the same as its parent context's content. Test 4 does work as the 1st element has the content H: which is different from H.
It doesn't seem to matter if you use the same scope (like in Test 1) or any other context you want to iterate through or even change the scope within the {{#with}} block.
The outcome of the above scenario is:

Combine [object Object] with H;
Combine H with O2;

Combine [object Object] with H;
Combine H with O2;

Combine [object Object] with H;
Combine H with O2:;

Combine H with H:;
Combine H with O2;

where as all the outputs should look like the 4th.
The same happens to the 2nd element if that's taken instead like in:

{{#with elements.carbonDioxide}} or {{#with elementsArray.[1]}}

but then to all other elements:

Combine O2 with H;
Combine [object Object] with O2;

Combine O2 with H;
Combine [object Object] with O2;

Combine O2 with H;
Combine O2 with O2:;

Combine O2 with H:;
Combine [object Object] with O2;

By the way, this doesn't seem to be related to the {{#with ..}} helper but also happens when replacing it with {{#each elementsArray}} or {{#each elements}}. So the bug is obviously somewhere in the scope finding part of the rendering engine.

@PitPik
Copy link

PitPik commented Jun 19, 2022

This bug is obviously being introduced by the version 4.x.x (v4.0.1 ... v4.7.7) as it works fine in 3.0.8.

@ulriklystbaek
Copy link
Author

ulriklystbaek commented Jun 20, 2022

Sorry for not seeing your reply before now. Like PitPik says, it is not related to root. You could also reproduce with this example:

Context: {"something": ["hallo", "fisk"]}
Template:
{{#with this.something.[0]}}
{{#each ../something}}{{../this}}{{/each}}
{{/with}}

Handlebars > 3.0.8: [object Object]hallo
Older handlebars (correct): hallohallo

It seems in the new versions of handlebars, going to parent scope, will not give correct content in first iteration.

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

No branches or pull requests

3 participants