Using Vue.js to iterate through a nested array from an object key

This is a complex v-for loop nested inside another v-for. It displays a list of questions along with the corresponding answers for each question. The key for the question will be used as the key for grouped_answers.

The structure of the v-for loop is shown below:

        <div v-for="question in questions.questions">
          {{question.question}}
          <div v-for="a in grouped_answers[0].answers">
            {{a.answer}}
          </div>
        </div>

Currently, it's throwing an error:

Cannot read property 'answers' of undefined.

An example of the grouped_answers object is provided below:

[
  {
    "question_id": 1,
    "answers": [
      {
        "id": 1,
        "answer": "Cat"
      },
      {
        "id": 2,
        "answer": "Dog"
      }
    ]
  },
  {
    "question_id": 2,
    "answers": [
      {
        "id": 3,
        "answer": "Fish"
      },
      {
        "id": 4,
        "answer": "Ant"
      }
    ]
  }
]

For the complete template code, please refer to the snippet below:

<template>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
              <!-- Existing HTML code -->
              <div v-for="question in questions.questions">
                {{question.question}}
                <div v-for="a in grouped_answers[0].answers" v-if="grouped_answers">
                  {{a.answer}}
                </div>
              </div>
              <br>
              <!-- Additional form elements -->
            </div>
        </div>
    </div>
</template>

<script>
    import axios from 'axios';
    export default {
      mounted() {
          console.log('Component ready.');
          this.appliances = JSON.parse(this.a);
          this.brands = JSON.parse(this.b);

      },

      props: ['a','b'],

        data: function() {
          return {
              appliances: '',
              appliance: '',
              brands: '',
              brand: '',
              age: '',
              first_name: '',
              last_name: '',
              phone_number: '',
              email: '',
              questions: '',
              answers: '',
              grouped_answers:'',
            }
        },
        methods: {
         getQuestions: function (){
           var self = this;
           axios.get('/get_questions/' + this.appliance)
            .then(function(response) {
                self.questions = response.data;
                self.getAnswers();
            })
            .catch(function(error) {
                console.log(error);
            });
         },
         getAnswers: function (){
           var self = this;
           axios.get('/get_answers/' + this.appliance)
              .then(function(response) {
                  self.answers = response.data;
                  self.putAnswers();
              })
              .catch(function(error) {
                  console.log(error);
              });
         },
         putAnswers: function (){
           var result = {};
           for (var i = 0; i < this.answers.answers.length; i++) {
             var question_id = this.answers.answers[i].question_id;
             if(!result[question_id]) {
                result[question_id] = {question_id: question_id, answers: []};
              }
              result[question_id].answers.push({
                id: this.answers.answers[i].id,
                answer: this.answers.answers[i].answer})
           }
           result = Object.keys(result).map(function (key) { return result[key]; });

           this.grouped_answers = result;

         },
       },
    }
</script>

UPDATE AFTER RECOMMENDATION

        <div v-for="question in questions.questions">
          {{question.question}}
          <div v-for="a in grouped_answers[0].answers" v-if="grouped_answers">
            {{a.answer}}
          </div>
        </div>

Answer №1

v-for has precedence over v-if in Vue.js, causing the loop to execute before any data is available. To address this issue, you can enclose the loop within a div or span and apply the v-if directive to that element. Here's an example:

<div v-for="question in questions.questions">
      {{question.question}}
      <div v-if="grouped_answers"&g
        <div v-for="a in grouped_answers[0].answers">
          {{a.answer}}
        </div>
      </div>
    </div>

You can find more information about this priority behavior in the Vue.js documentation here:

https://v2.vuejs.org/v2/guide/list.html#v-for-with-v-if

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Looking for an iframe that can adapt to varying content sizes and scale seamlessly with different screen dimensions?

I am new to advanced coding and currently working on my first responsive Wordpress site. I have a "Product Search" database/site that I'm trying to integrate into my website using an iFrame. I want the integration to look seamless without scroll bars ...

What is the process for displaying a vnode (slot of a vue component) and attaching it to a specific element?

Consider the scenario where a dialog component is present. ... <dialog> <div> {{data}} </div> </dialog> ... Because of the stack context limitations, it can be challenging to keep the dialog always at the topmost position ...

Identify the nested Object within the Json data

I am looking to add and name a nested object within my Json data structure. The current structure of my Json is as follows: { "MH": [ { "MHF46": "Ledig", "MHF60": "60", }, ...

What is the reason behind taps in TypeScript only registering the first tap event?

One issue I am encountering is that only the first tap works when clicked, and subsequent taps result in an error message: Uncaught TypeError: Cannot read properties of undefined (reading 'classList') Here is the code I am using: https://codepen ...

CompletePage script, individual automatic scrolling

Having trouble with my fullPage.js implementation. I have a total of 5 sections and I'm trying to set different scrolling behaviors for each section. Specifically, I want Sections 1 through 3 to auto-scroll and Section 4.1 to 4.2 to use normal scroll. ...

Start the Vuepress build process and run the generated project

I have created a basic Vuepress project with PWA support. Currently, Vuepress only offers two scripts: "scripts": { "docs:dev": "vuepress dev docs", "docs:build": "vuepress build docs" } The de ...

Maximizing Component Reusability and Persisting Data in Vue

As I continue to work on multiple projects, I find myself reusing linked Vue components that I have created. Currently, I am manually passing data between these components using props and emits. However, this process has become inefficient as the component ...

Reduce the amount of time it takes for a Google AdWords Script to generate a

According to Google Script best practices, it is recommended to store operations in an array and then call the methods once all the operations have been constructed. This helps minimize response time each time a service is called. For example, let's ...

Having difficulty aligning ListItem to the right within a List

I am working with an array that contains objects which I need to display in ListItems of a List. My goal is to show these ListItems from the array Objects in a layout where odd numbers are on the left and even numbers are on the right. However, I am facing ...

Ajax request and the Ghostery extension in Firefox

I've implemented the following code to detect ad blockers like Ghostery: <script> var request = new XMLHttpRequest(); request.onreadystatechange = function() { if(request.readyState === 4 && request.status === 200 ) { ...

What is the best way to turn my thumbnail into a clickable link while having the title positioned to the right?

Is there a way to create a thumbnail that acts as a link and position the title next to the thumbnail? I have experimented with using 'after' and modifying the HTML structure to align them horizontally. Any ideas on how I can achieve this layou ...

When using `setState()`, ensure that you are updating a component that is already mounted or in the process of mounting. If you receive this error, it

When using WebSocket to communicate with my server, I call the handleSubmit() function to send data and update my state based on the received response. Everything works fine initially. Upon calling componentWillUnmount, I stop sending data to the websocke ...

Error: Unable to locate specified column in Angular Material table

I don't understand why I am encountering this error in my code: ERROR Error: Could not find column with id "continent". I thought I had added the display column part correctly, so I'm unsure why this error is happening. <div class="exa ...

Python: increasing index range by 1 unit

Below is a snippet of code that I am working on: f = open('story.txt', 'r') story = f.read() a = 0 b = 2 active_words = story[a:b] I want to modify this code so that later in the program, I can dynamically increase the range of the ...

Utilizing vue-router-next without a bundler: A step-by-step guide

Previously, the vue-router plugin would automatically mount to the global application instance like this: if (inBrowser && window.Vue) { window.Vue.use(VueRouter); } In Vue 3, this functionality has been restricted. So, how can I access VueRoute ...

Utilizing JavaScript for validation on an ASPX page within Visual Studio

After entering an email ID in a textbox, the email validation process is initiated. However, it seems that there is an issue where the entire function may not be executed properly. <head runat="server"> <title></title> ...

Utilize AJAX to dynamically refresh the page without having to reload it, enabling the use of both POST and GET methods

In order to avoid reloading the page when refreshing, I am utilizing Ajax for this particular 3-sided content along with JavaScript. Here is the code: Content: <ul id="nav"> <li><a href="ajax_adat.php?id=8&epul=0">Data</a>< ...

unable to establish connection due to port error in node.js

While executing node app.js I encountered the following error message info - socket.io started warn - error raised: Error: listen EACCES This snippet shows all the JavaScript code within the application. After running sudo supervisor app.js T ...

Update the objects with new values when the user makes changes in the

I am working with dynamically created input fields const [data, setData] = useState({ native: [{}], rolls: [{}] }) // initial data {navtive?.map((item, index) => { return ( <input type="text" name={item.id} ...

Transform a nested for loop into a map representation

For instance: for x in iterable1: expression The map method can be used as follows: map(lambda x: expression, iterable1) Is there a way to expand this to a nested for loop using only the map function and without utilizing list comprehensions? For ...