0

I have been searching for hours for a simple example on this, so I've come to the SO community for help.

If I have a json object (external, let's say we've accessed it as "Info") with arrays like this...

{
"Job": {
    "JobId": "123",
    "Tasks": [
        {
            "TaskId": "1",
            "TaskName": "Test Task 1",
            "SubTasks": [
            {
                "SubTaskId": "1",
                "SubTaskName": "Test Sub Task 1"
            },
            {
                "SubTaskId": "2",
                "SubTaskName": "Test Sub Task 2"
            },
            {
                "SubTaskId": "3",
                "SubTaskName": "Test Sub Task 3"
            }
            ]
        },   
        {
            "TaskId": "2",
            "TaskName": "Test Task 2",
            "SubTasks": [
            {
                "SubTaskId": "1",
                "SubTaskName": "Test Sub Task 1"
            },
            {
                "SubTaskId": "2",
                "SubTaskName": "Test Sub Task 2"
            },
            {
                "SubTaskId": "3",
                "SubTaskName": "Test Sub Task 3"
            }
            ]
        }, 
        {
            "TaskId": "3",
            "TaskName": "Test Task 3",
            "SubTasks": [
            {
                "SubTaskId": "1",
                "SubTaskName": "Test Sub Task 1"
            },
            {
                "SubTaskId": "2",
                "SubTaskName": "Test Sub Task 2"
            },
            {
                "SubTaskId": "3",
                "SubTaskName": "Test Sub Task 3"
            }
            ]
        }
    ]
} 
}

How do I access that in a Vue instance and access the nested arrays? Every example I can find is either woefully over my head, or looks like the following:

new Vue({
    el: "ID1",
    data: {
        items: [
            { message: 'Foo' },
            { message: 'Bar' }
        ]
    }
})

However I already know how to use v-for to get data from an array that's already in the instance (hardcoded in I mean), though the nested arrays still escape me a little, but I can't for the life of me figure out a straightforward way to get the access to the arrays and nested arrays if they are in a json object w/arrays.

I've tried just putting "Data" in the instance as follows to get the object:

new Vue({
    el: "ID1",
    data: Info
})

or

new Vue({
    el: "ID1",
        data: {
            items: Info,
            /// extra stuff here 
    }
})

It works as far as I can access the object (Info), but I run into an error when trying to use something like v-for="Task in Tasks" (as an example) "Property or method "Tasks" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for classed-based components, by initializing the property".

I'd like to be able to do:

<div id="ID1">
    <ul>
        <li v-for="Task in Tasks">{{ Task.TaskId }}</li>
    </ul>
</div>

or further:

<div id="ID1">
    <ul>
        <li v-for="SubTask in SubTasks">{{ SubTask.SubTaskId }}</li>
    </ul>
</div>

I know those don't work, just want to give an example.

Any help would be wildly appreciated on this. Feel free to take me to Vue 101. I'm not sure what else to ask or what to provide to make it a better question. I would normally not ask a question this broad, I would normally take the time to actually learn how to do this but I am stuck and trying to get some things done for tomorrow and pretty frustrated at this point. I've used nested forEach loops in JS and output with JQuery tons of times but I just can't figure out this logic in Vue. Thanks in advance.

Phil
  • 157,677
  • 23
  • 242
  • 245
PhilT41
  • 99
  • 1
  • 8
  • 2
    Everything in your `Info` object is within its `Job` property so you want something like `v-for="Task in Job.Tasks"` – Phil Jun 14 '19 at 00:01
  • 1
    Possible duplicate of [How can I access and process nested objects, arrays or JSON?](https://stackoverflow.com/questions/11922383/how-can-i-access-and-process-nested-objects-arrays-or-json) – Phil Jun 14 '19 at 00:02
  • @Phil Thank you for providing both the information and the possible duplicate. I hadn't seen that article. Much appreciated. – PhilT41 Jun 14 '19 at 01:40

1 Answers1

0

If you add it to your data like this...

data: {
    items: Info
}

... then you'd access it as items within your template.

As your data has some nesting the tasks would be available as items.Job.Tasks. Here the . for accessing properties works just like it would in any other JavaScript context. Similarly the square bracket notation is also available should you need it.

So something like v-for="task in items.Job.Tasks" would create a loop over your tasks and a local variable called task would be created for each item. This is just like when you're using forEach to loop over an array, e.g. items.Job.Tasks.forEach(task => {...}).

To get at the sub-tasks you'd then use v-for="subTask in task.SubTasks".

A complete example:

const Info = {
  "Job": {
    "JobId": "123",
    "Tasks": [{
        "TaskId": "1",
        "TaskName": "Test Task 1",
        "SubTasks": [{
            "SubTaskId": "1",
            "SubTaskName": "Test Sub Task 1"
          },
          {
            "SubTaskId": "2",
            "SubTaskName": "Test Sub Task 2"
          },
          {
            "SubTaskId": "3",
            "SubTaskName": "Test Sub Task 3"
          }
        ]
      },
      {
        "TaskId": "2",
        "TaskName": "Test Task 2",
        "SubTasks": [{
            "SubTaskId": "1",
            "SubTaskName": "Test Sub Task 1"
          },
          {
            "SubTaskId": "2",
            "SubTaskName": "Test Sub Task 2"
          },
          {
            "SubTaskId": "3",
            "SubTaskName": "Test Sub Task 3"
          }
        ]
      },
      {
        "TaskId": "3",
        "TaskName": "Test Task 3",
        "SubTasks": [{
            "SubTaskId": "1",
            "SubTaskName": "Test Sub Task 1"
          },
          {
            "SubTaskId": "2",
            "SubTaskName": "Test Sub Task 2"
          },
          {
            "SubTaskId": "3",
            "SubTaskName": "Test Sub Task 3"
          }
        ]
      }
    ]
  }
}

new Vue({
  el: "#ID1",
  data: {
    items: Info
  }
})
<script src="https://unpkg.com/vue@2.6.10/dist/vue.js"></script>
<div id="ID1">
  <ul>
    <li v-for="task in items.Job.Tasks">
      {{ task.TaskId }} - {{ task.TaskName }}
      <ul>
        <li v-for="subTask in task.SubTasks">
          {{ subTask.SubTaskId }} - {{ subTask.SubTaskName }}
        </li>
      </ul>
    </li>
  </ul>
</div>
skirtle
  • 27,868
  • 4
  • 42
  • 57
  • Thank you for this. I was not nesting correctly in my html template and complicating my instance as well. Thank you again, I've marked this as the answer. – PhilT41 Jun 14 '19 at 01:44