Using V-model to bind to an object dynamically created in an array

I am trying to create objects dynamically in an array and use v-model with an input. Here is my code snippet:

This is the array structure

new_questions:{
    questionrecord: []
}

This is the input field setup

<div class="form-fields" v-for="(field, index) in question_fields">
    <div class="form-group">
        <select class="form-control" v-model="new_questions.questionrecord[index].questionresponse">
            <option value="single_answer">Single Answer (For regular question)</option>
            <option value="multiple_answer">Multiple Answer (For situational judgement question)</option>
        </select>
    </div>
</div>

The expected output of the array should be like

new_questions:{
    questionrecord: [
        {
            questiontype: "single_answer"
        },
        {
            questiontype: "multiple_answer"
        },
        ...
    ]
}

However, I encounter an error message:

[Vue warn]: Error in render: "TypeError: Cannot read property 'questionresponse' of undefined

Can anyone advise on how to fix this issue?

Answer №1

The V-Model simplifies the syntax for handling input and value bindings.

If you need to manipulate data in a way that involves distinguishing between input and value properties, you may have to create a setter method that can handle dynamically changing or even non-existent properties.

Depending on the complexity of your data structure and whether you need to work with properties at different nested levels, your setter method could become quite intricate. Utilizing helpers like lodash.setWith might make this task easier.

Here's a specific example tailored to your scenario:

<template>
...
  <div class="form-fields" v-for="(field, index) in question_fields">
    <div class="form-group">
      <select class="form-control"
       :value="new_questions.questionrecord[index].questionresponse"
       @input="setValue($event.target.value, index)"
      >
        <option value="single_answer">Single Answer (For regular question)</option>
        <option value="multiple_answer">Multiple Answer (For situational judgement question)</option>
      </select>
    </div>
  </div>
...
</template>

<script>
export default {
  data() {
    return {
      new_questions: {
        questionrecord: [],
      }
    };
  },

  created() {
    // prepopulate your questionrecord array so you don't throw TypeErrors
    const dummyArray = Array(this.question_fields.length);
    this.new_questions.questionrecord.push(...dummyArray);
  },

  methods() {
    setValue(value, index) {
      const newRecord = {
        questionresponse: value,
      };
      // To properly update Vue array entries, avoid setting values by index directly
      this.new_questions.questionrecord.splice(index, 1, newRecord);
      // Use Vue.set(rootObj, key, value) for creating object properties
    }
  }
};
</script>

Answer №2

Not sure what your question_fields look like, but I tested this code with some placeholder values and it worked fine for me.

new Vue({
  el: "#app",
  data() {
    return {
      question_fields: ['test', 'test1'],
      new_questions:{
          questionrecord: [
              {
                  questiontype: "single_answer"
              },
              {
                  questiontype: "multiple_answer"
              }
          ]
      }
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div class="form-fields" v-for="(field, index) in question_fields">
    <div class="form-group">
      <select class="form-control" v-model="new_questions.questionrecord[index].questionresponse">
        <option value="single_answer">Single Answer (For regular question)</option>
        <option value="multiple_answer">Multiple Answer (For situational judgement question)</option>
      </select>
    </div>
  </div>
  
   <pre>{{new_questions.questionrecord}}</pre>
</div>

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

Making text strike-through when checkbox is marked

I am currently working on developing a To-Do list application using express and EJS middleware. The main feature of this app is to display a list of tasks with checkboxes next to each task added. When a task is completed, the user can mark it as done by ch ...

As the second line of Javascript code is being executed, the first line is still

I have a task where I need to execute a SQL SELECT statement and save the results. Then, those results need to be passed into a function to generate a graph using the data points provided. Refer to the code snippet below for details. var dataKWhr = getCov ...

The use of fs.writeFileSync is invalid and will not work for this operation

Encountering an issue while working with fs in next.js, receiving the following error message: TypeError: fs.writeFileSync is not a function Here's a snippet from my package.json: resolve: { fallback: { "fs": false }, } ...

Setting the ng-href attribute in Angular conditionally using a function

How can I dynamically set links in an angular controller based on a function's result? <a ng-href="{{ setLink('contact') }}" Inside the controller: angular.module("my-app") .controller('navController', ['$scope&apos ...

Using the scrollIntoView() method in VUE.js to center an li element within a component

One of the components I'm working with has multiple list items, and I want to achieve a functionality where clicking on any item will center it inside the component, making it visible in the center of the view. <card-maintenance v-for="m ...

Tips for triggering the .click() function upon returning to index.html after visiting a different page

I'm in the process of creating a portfolio website where the index.html page features a sliding navigation bar that displays a collection of projects. Each project is linked to a separate work.html page. I would like the sliding nav to automatically o ...

Issue with passing function argument through ng-change event is not being resolved

I have a collection of objects with both name and url properties. Utilizing ng-options, I am able to present the name property of each object in a select list. Subsequently, I utilize ng-change to trigger a function with the selected object's url as ...

What is the best method to loop through this object with JavaScript?

Suppose I have the following data: let testData = { 'numGroup1': [[(1, 2, 3, 4, 5), (5, 6, 7, 8, 9)]], 'numGroup2': [[(10, 11, 12, 13, 14), (15, 16, 17, 18, 19)]] }; What is the best approach to iterate through this data using Jav ...

What is the best way to successfully send an object through AJAX once all its updates are completed?

I am experiencing an issue with my JavaScript code within an event: var userData = tableWidget.grid('userData'); console.log(tableWidget.grid('userData')); $.ajax({ "url": "../../server/query.aspx?tableEvent=reordercolumns&tabl ...

Tips for building a diverse array of data types and effectively utilizing them based on their specific type in Typescript

Trying to store both custom types, Graphic and Asset, in the same array is proving to be a challenge. The goal is to access them and retain their individual type information. const trail: Array<Graphic | Asset> = []; for (let index = 0; index < t ...

inability to conceal a two-dimensional marker array within Google Maps API v3

I need some help with my marker that refuses to hide Even after using setMap, my marker is still visible on the map Here is the error message from the console Please assist! Thank you in advance markers[i][j].setMap(null); markers.setMap(null); va ...

Having trouble establishing a connection to MySQL through NodeJS and Express

I am currently attempting to establish a connection to MySQL using a nodeJS app with express as the server. I have referred to the mysql npm documentation to start the connection process, but I keep encountering an error in the callback function within cre ...

Tips for resolving the problem of Google Maps repeatedly appearing when utilizing the Auto-Loading feature

I need help understanding the issue that arose when loading the Google Maps API. "You have included the Google Maps API multiple times on this page. This may cause unexpected errors." This error occurred while attempting to automatically load the API. B ...

Calculate the sum of each row within a grouped object

My task is to sum up the values of minutes and seconds_left, then group them by id_project. 0: {id_project: 2, minutes: 12, seconds_left: NaN} 1: {id_project: 3, minutes: 15, seconds_left: 11} 2: {id_project: 4, minutes: 0, seconds_left: 11} 3: {id_projec ...

REACT Error: Unable to access the 'value' property as it is undefined

I'm having an issue with my code while trying to render my react app and I just can't seem to figure it out. As a beginner, I am attempting to create a basic counter that I plan to use as a shopping basket. Can someone lend me a hand? import Rea ...

Display an icon before an active v-list-item in Vuetify 3's v-list

I need help figuring out how to add an icon to a v-list-item only if it is active. <v-list class="px-15 pt-5" border density="compact"> <v-list-item v-for="(item,i) in items"> <!-- Need assistance putting ...

Using jQuery to create a fade in/fade out effect within a list of items

I'm currently experimenting with jQuery's fadeIn/fadeOut effects on images used as buttons within an unordered list. My goal is to have the hovered image fade in quickly and out slowly upon mouseout. The issue I'm encountering is related to ...

Divide arrays and merge them into new arrays depending on their position using indexOf in JavaScript

I am looking for a way to iterate through multiple arrays, for example: array1 = [ "1", "2", "3" ]; array2 = [ "a", "b", "c" ]; array3 = [ "apples", "bananas", "cheese" ]; I want to combine them into new arrays based on their index positions like this: ...

Is there a way to create a list of languages spoken using Angular?

I am in search of a solution to create a <select> that contains all the language names from around the world. The challenge is, I need this list to be available in multiple languages as well. Currently, I am working with Angular 8 and ngx-translate, ...

Retrieve elements within the array ranging from index 1 to 5 using Javascript

How can I log items from index 1 to 5 in the current array by using a loop? let cars = ["AUDI","BMW","LEXUS","VOLKSWAGEN","FERRARY","PORSCHE"] for (let i = 0; i < cars.length; i++) { if (i >= 1 && i <= 5) { console.log("The current ...