access array elements by index, inside a section - BUG #207

Closed
aresn opened this Issue Dec 17, 2012 · 14 comments

Comments

Projects
None yet
5 participants
@aresn

aresn commented Dec 17, 2012

Context looks like this :

{objects: [id1, id2, id3 ,...]
likes:[true,true,false,...]
}

In my template I loop over the 'objects' array. Inside this loop I have access to likes array, but not each elements of likes array individually.

This works
{#objects} {likes} {/object}

and this one doesn't
{#objects} {likes[0]}{/object}

Am I missing something ?

@vybs

This comment has been minimized.

Show comment Hide comment
@vybs

vybs Dec 17, 2012

Contributor

have you tried the example here

http://linkedin.github.com/dustjs/test/test.html

under this select "array" example


{
  "do": {
    "re": ["hello!", "bye!"]
  }
}

{do.re[0]}

output:

hello!


{
  "A": [{
    "B": [{
      "C": ["Ca1", "C2"]
    },
    {
      "C": ["Ca2", "Ca22"]
    }]
  },
  {
    "B": [{
      "C": ["Cb1", "C2"]
    },
    {
      "C": ["Cb2", "Ca2"]
    }]
  }]
}
{#A}A loop:{$idx}-{$len},{#B}B loop:{$idx}-{$len}C[0]={.C[0]} {/B}A loop trailing: {$idx}-{$len}{/A}

output

A loop:0-2,B loop:0-2C[0]=Ca1 B loop:1-2C[0]=Ca2 A loop trailing: 0-2A loop:1-2,B loop:0-2C[0]=Cb1 B loop:1-2C[0]=Cb2 A loop trailing: 1-2

Contributor

vybs commented Dec 17, 2012

have you tried the example here

http://linkedin.github.com/dustjs/test/test.html

under this select "array" example


{
  "do": {
    "re": ["hello!", "bye!"]
  }
}

{do.re[0]}

output:

hello!


{
  "A": [{
    "B": [{
      "C": ["Ca1", "C2"]
    },
    {
      "C": ["Ca2", "Ca22"]
    }]
  },
  {
    "B": [{
      "C": ["Cb1", "C2"]
    },
    {
      "C": ["Cb2", "Ca2"]
    }]
  }]
}
{#A}A loop:{$idx}-{$len},{#B}B loop:{$idx}-{$len}C[0]={.C[0]} {/B}A loop trailing: {$idx}-{$len}{/A}

output

A loop:0-2,B loop:0-2C[0]=Ca1 B loop:1-2C[0]=Ca2 A loop trailing: 0-2A loop:1-2,B loop:0-2C[0]=Cb1 B loop:1-2C[0]=Cb2 A loop trailing: 1-2

@aresn

This comment has been minimized.

Show comment Hide comment
@aresn

aresn Dec 17, 2012

Yes , in that example 're' is inside 'do' object. What I have is a bit different. I have two separate arrays. array1 , and array2 . These two arrays have the same cardinality . One represents an array of objects and the other says something about the relationship between the current logged-in user and those objects.

I have a loop like this : {#array1} {/array1}, And I like to check if the user has liked the current object or not, so I like to do something like this
{#array1}
check this: {array2[$idx]}
{/array1}

aresn commented Dec 17, 2012

Yes , in that example 're' is inside 'do' object. What I have is a bit different. I have two separate arrays. array1 , and array2 . These two arrays have the same cardinality . One represents an array of objects and the other says something about the relationship between the current logged-in user and those objects.

I have a loop like this : {#array1} {/array1}, And I like to check if the user has liked the current object or not, so I like to do something like this
{#array1}
check this: {array2[$idx]}
{/array1}

@aresn

This comment has been minimized.

Show comment Hide comment
@aresn

aresn Dec 17, 2012

Context:
{
arr1:[1,2,3],
arr2:[4,5,6]
}

Template:
{#arr1}
{arr2[0]}
{~n}
{/arr1}

Output:
"Nothing"

aresn commented Dec 17, 2012

Context:
{
arr1:[1,2,3],
arr2:[4,5,6]
}

Template:
{#arr1}
{arr2[0]}
{~n}
{/arr1}

Output:
"Nothing"

@vybs

This comment has been minimized.

Show comment Hide comment
@vybs

vybs Dec 17, 2012

Contributor

if arr2 is not inside arr1, dust will not recognize the inner element, this is nothing specific to arrays, it is the same with any other data access

try this


{#arr1}
{#arr2}
{arr2[0]}
{~n}
{/arr2}
{/arr1}



Contributor

vybs commented Dec 17, 2012

if arr2 is not inside arr1, dust will not recognize the inner element, this is nothing specific to arrays, it is the same with any other data access

try this


{#arr1}
{#arr2}
{arr2[0]}
{~n}
{/arr2}
{/arr1}



@aresn

This comment has been minimized.

Show comment Hide comment
@aresn

aresn Dec 17, 2012

Thank you, but I still get nothing with

{#arr1}
{#arr2}
{arr2[0]}
{/arr2}
{/arr1}

context:
{
arr1:[1,2,3],
arr2:[4,5,6]
}

Update: I tried
{#arr1}
{arr1[0]}
{/arr1}

and still I get nothing.

aresn commented Dec 17, 2012

Thank you, but I still get nothing with

{#arr1}
{#arr2}
{arr2[0]}
{/arr2}
{/arr1}

context:
{
arr1:[1,2,3],
arr2:[4,5,6]
}

Update: I tried
{#arr1}
{arr1[0]}
{/arr1}

and still I get nothing.

@vybs

This comment has been minimized.

Show comment Hide comment
@vybs

vybs Dec 17, 2012

Contributor

@aresn you are right, since the folowing works

{#arr1}
{arr2}
{~n}
{/arr1}

the compiled template looks like this

function body_1(chk, ctx) {
    return chk.reference(ctx.get("arr2"), ctx, "h").write("\n");
  }
  return body_0;

the below should also work, it is a bug
{#arr1}
{arr2[0]}
{~n}
{/arr1}

since get is replaced with getPath

function body_1(chk, ctx) {
return chk.reference(ctx.getPath(false, ["arr2", "0"]), ctx, "h").write("\n");
}

@jairodemorais since he worked on this feature can help fix the BUG

Contributor

vybs commented Dec 17, 2012

@aresn you are right, since the folowing works

{#arr1}
{arr2}
{~n}
{/arr1}

the compiled template looks like this

function body_1(chk, ctx) {
    return chk.reference(ctx.get("arr2"), ctx, "h").write("\n");
  }
  return body_0;

the below should also work, it is a bug
{#arr1}
{arr2[0]}
{~n}
{/arr1}

since get is replaced with getPath

function body_1(chk, ctx) {
return chk.reference(ctx.getPath(false, ["arr2", "0"]), ctx, "h").write("\n");
}

@jairodemorais since he worked on this feature can help fix the BUG

@jairodemorais

This comment has been minimized.

Show comment Hide comment
@jairodemorais

jairodemorais Dec 28, 2012

Contributor

@aresn, thanks for the info and sorry for the delay I was on vacation. I will take a look ASAP.

Contributor

jairodemorais commented Dec 28, 2012

@aresn, thanks for the info and sorry for the delay I was on vacation. I will take a look ASAP.

@rragan

This comment has been minimized.

Show comment Hide comment
@rragan

rragan Dec 28, 2012

Contributor

I guess {arr2[$idx]} would also need to work for this use. Be sure to test that case.

Contributor

rragan commented Dec 28, 2012

I guess {arr2[$idx]} would also need to work for this use. Be sure to test that case.

@aresn

This comment has been minimized.

Show comment Hide comment
@aresn

aresn Dec 29, 2012

Thank you @jairodemorais. Would you please post your fix here ? I spent hours trying to understand dust in order to fix this and couple of times, I thought I fixed it, but then I realized I broke the code :/

aresn commented Dec 29, 2012

Thank you @jairodemorais. Would you please post your fix here ? I spent hours trying to understand dust in order to fix this and couple of times, I thought I fixed it, but then I realized I broke the code :/

@jairodemorais

This comment has been minimized.

Show comment Hide comment
@jairodemorais

jairodemorais Jan 4, 2013

Contributor

hi @aresn @vybs

WE have only one problem with this case because When dust find an array and start looping over it, dust creates a new context using the current element. You can see it documented in the code.

/*
  Dust's default behavior is to enumerate over the array elem, passing each object in the array to the block.
  When elem resolves to a value or object instead of an array, Dust sets the current context to the value 
  and renders the block one time.
  */

So in order to get the value of arr2 inside arr1 loop we should walk the context up maybe using the @rragan helper.

Contributor

jairodemorais commented Jan 4, 2013

hi @aresn @vybs

WE have only one problem with this case because When dust find an array and start looping over it, dust creates a new context using the current element. You can see it documented in the code.

/*
  Dust's default behavior is to enumerate over the array elem, passing each object in the array to the block.
  When elem resolves to a value or object instead of an array, Dust sets the current context to the value 
  and renders the block one time.
  */

So in order to get the value of arr2 inside arr1 loop we should walk the context up maybe using the @rragan helper.

@rragan

This comment has been minimized.

Show comment Hide comment
@rragan

rragan Jan 4, 2013

Contributor

I tested
Template:
{#arr1}
{@access key="arr2[0]" /}
{/arr1}
using my access helper that is in the pull request queue for dustjs-helpers and got Template:444 as expected. Also
Template:
{#arr1}
{@access key="arr2[{$idx}]" /}
{/arr1}
outputs Template:456 as expected.

Back to the general point -- at first blush I expected this to work:
{#arr1}
{#arr2}
{.[0]}
{/arr2}
{/arr1}
but it does not. What users do not generally understand is that {arr[subscript]} generates a getPath call even though in most language an array element reference can be used anywhere a scalar can be used. Turning this into a getPath call immediately triggers the issues surrounding what context currently is. I don't know how feasible it would be to make an array element reference not call getPath but instead do the equivalent of a get with subscripting.

Contributor

rragan commented Jan 4, 2013

I tested
Template:
{#arr1}
{@access key="arr2[0]" /}
{/arr1}
using my access helper that is in the pull request queue for dustjs-helpers and got Template:444 as expected. Also
Template:
{#arr1}
{@access key="arr2[{$idx}]" /}
{/arr1}
outputs Template:456 as expected.

Back to the general point -- at first blush I expected this to work:
{#arr1}
{#arr2}
{.[0]}
{/arr2}
{/arr1}
but it does not. What users do not generally understand is that {arr[subscript]} generates a getPath call even though in most language an array element reference can be used anywhere a scalar can be used. Turning this into a getPath call immediately triggers the issues surrounding what context currently is. I don't know how feasible it would be to make an array element reference not call getPath but instead do the equivalent of a get with subscripting.

@cmcn

This comment has been minimized.

Show comment Hide comment
@cmcn

cmcn Mar 21, 2013

Any chance there's a fix in the works for this?

Also: http://www.xkcd.com/979

cmcn commented Mar 21, 2013

Any chance there's a fix in the works for this?

Also: http://www.xkcd.com/979

@vybs

This comment has been minimized.

Show comment Hide comment
@vybs

vybs Mar 21, 2013

Contributor

@ctm814 we hear you.:)

Contributor

vybs commented Mar 21, 2013

@ctm814 we hear you.:)

@rragan

This comment has been minimized.

Show comment Hide comment
@rragan

rragan Dec 13, 2013

Contributor

Ran the initial example and it works now. This got fixed by the path change in dust 2.0

true,true,false true,true,false true,true,false

true true true

Contributor

rragan commented Dec 13, 2013

Ran the initial example and it works now. This got fixed by the path change in dust 2.0

true,true,false true,true,false true,true,false

true true true

@rragan rragan closed this Dec 13, 2013

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