Search code examples
meteormeteor-blazemeteor-helper

Nested #Each values are not available outside of the context


I'm having a nested each pair like this: {{#each goal in goals}}

<template name="task">
{{#each goal in goals}}
 {{#each task in relatedTasks goal}}
<li>
<span class="text task"><a href="#modal-taskedit" data-toggle="modal"><strong>{{task.taskName}}</strong></a> to {{goal.goalName}}<br> taskid: {{task._id}}
{{task.taskPostpone}}</span>
    {{#afModal class="btn btn-primary" collection="Tasks" operation="update" doc=task._id}}
  Update {{task.taskName}}
{{/afModal}}
</li> 
      {{/each}}
 {{/each}}    

</template>

and would like to get the value of the task._id in my client.js like here:

Template.task.events({
    'click .task': function() {
    Session.set("selectedTask", this._id);
        //console.log(this._id);
        //console.log(goal._id);
        console.log(task._id);
        //console.log('Click event happened: this._id saved as selectedItem Session variable.');
  } 
  });

When I click on a task I receive this error on the console: "undefined" and I don't really understand the reason behind. I did some research and found a possible solution: Maybe 'click .task': function(task) should receive the task context or input so it could be able to grasp the meaning of this._id. I have a {{#afModal doc=task._id}} which also should receive the value of task._id and does not seem to work, although it is placed in the right context I think. I have a feeling that the two issues are related somehow.


Solution

  • The problem is that the {{#each goal in goals}} loop syntax does not change the data context within the loop (see docs). It simply adds a goal variable for use in your spacebars template.

    One solution would be to move the contents of the {{#each task in ...}} loop to another template like so.

    <template name="task">
        {{#each goal in goals}}
            {{#each task in relatedTasks goal}}
                {{> goalTask goal=goal task=task}}
            {{/each}}
        {{/each}}
    </template>
    
    <template name="goalTask">
        <li>
            <span class="text task">
                <a href="#modal-taskedit" data-toggle="modal"><strong>{{task.taskName}}</strong></a>
                to {{goal.goalName}}<br>
                taskid: {{task._id}} {{task.taskPostpone}}
            </span>
            {{#afModal class="btn btn-primary" collection="Tasks" operation="update" doc=task._id}}
                Update {{task.taskName}}
            {{/afModal}}
        </li>
    </template>
    

    Your event handler would then look like this.

    Template.goalTask.events({
        'click .task': function() {
            console.log(this.goal._id);
            console.log(this.task._id);
        } 
    });