Creating a list repeater using v-for in Vue.js 2 with computed property

Seeking assistance with adding computed columns to a table (last three columns). Suspecting the issue lies in the computed property not correctly referencing the record. Any simple solutions that I might be overlooking? Appreciate any thoughts or insights!

Link to the fiddle: https://jsfiddle.net/0770ct39/2/

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Vue.js Tutorial | More Computed Properties</title>

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  </head>

  <body>
    <div id="app" class="container">
      <div class="row">
            <table class="table table-hover">
                <thead>
                    <tr>
                        <th>Phase</th>
                        <th>Labour Budget</th>
                        <th>Labour Hours</th>
                        <th>Labour Cost Rate</th>
                        <th>Labour Cost</th>
                        <th>Overhead Cost</th>
                        <th>Net</th>
                    </tr>   
                </thead>
                <tbody>
                    <tr v-for="record in records">
                        <td>{{record.phase}}</td>
                        <td>{{record.labourBudget}}</td>
                        <td><input type="text" v-model="record.labourHours"></td>
                        <td><input type="text" v-model="record.labourCostRate"></td>
                        <td>{{record.labourCost}}</td>
                        <td>{{record.overheadCost}}</td>
                        <td>{{record.net}}</td>
                    </tr>
                </tbody>
            </table>
      </div>
    </div>
  </body>

  <script src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="83f5f6e6c3b1adb3adb0">[email protected]</a>/dist/vue.js"></script>

  <script>
    var app = new Vue({
      el: '#app',
      data: {
        records: [
            {phase:"Phase1", labourBudget: 100, labourHours: 4, labourCostRate: 45},
            {phase:"Phase2", labourBudget: 100, labourHours: 2, labourCostRate: 42}
        ]
      },
      computed: {
        labourCost: function(){
            return this.record.labourHours * this.record.labourCostRate;
        },
        overheadCost: function(){
            return this.record.labourCost * 1.36;
        },
        net: function(){
            return this.record.netRevenue-this.record.labourCost-this.record.overheadCost;
        }
      }
    })
  </script>
</html>

Answer №1

Your computed property functions may not be working properly due to the fact that the keyword this refers to your Vue instance. To illustrate, if you were to adjust your computed functions in this manner...

computed: {
  labourCost: function() {
    return app.record.labourHours * app.record.labourCostRate;
  }
}

...it would essentially have the same functionality as your current setup because the variable app points back to your Vue instance.

In its present state, when Vue processes your computed properties, it will encounter an issue where it cannot find a data property named record. Although there is one called records, none are specifically named record.

I suggest returning a computed array containing all the records like this:

var app = new Vue({
  el: '#app',
  data: {
    records: [
        {phase:"Phase1", labourBudget: 100, labourHours: 4, labourCostRate: 45},
        {phase:"Phase2", labourBudget: 100, labourHours: 2, labourCostRate: 42}
    ]
  },
  computed: {
    rows: function() {
      return this.records.map(function(record) {
        return Object.assign({}, record, {
          labourCost : record.labourHours * record.labourCostRate,
          overheadCost : record.labourCost * 1.36,
          net : record.netRevenue-record.labourCost-record.overheadCost
        });
      });
    }
  }
})

Subsequently, update the loop in your HTML to

<tr v-for="record in rows">

NOTE: Object.assign() is part of ES2015. You have the option of using this polyfill. Alternatively, consider utilizing object-merge functions like lodash's _.assign or jQuery.extend().

Answer №2

To make this functionality work, you should consider separating each row into its own component and passing the 'record' data as a prop. Alternatively, if you prefer not to create separate components, you can utilize methods instead.

For example:

methods: {
  laborCost: function(record) {
    return record.labourHours * record.labourCostRate
  },
  ...
}

You can then call this method like so:

{{ laborCost(record) }}

If you choose to go the component route (which is recommended), you would do something like this:

<record v-for="record in records" :record="record"></record>

You can then transfer those computed properties into the component, ensuring that it functions as intended.

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

Switch back and forth between adding and removing a table row using jQuery

Currently, I am developing a drop-down feature for a table that populates its data using MySQL. The functionality involves creating a new table row below the current one when a user clicks a button. However, instead of generating multiple new rows each tim ...

Ensure the item chosen is displayed on a single line, not two

I've encountered an issue with my select menu. When I click on it, the options are displayed in a single line. However, upon selecting an item, it appears on two lines - one for the text and another for the icon. How can I ensure that the selection re ...

React Native: LogBox now including all warnings

Looking for a way to use LogBox to filter out specific log messages, but despite my attempts to ignore them, they still show up in the console... "react-native": "0.68.2", In my main file (index.js), this is how I've tried to impl ...

Validation with vee-validate performed instantly after inputting every character

Is it possible to validate after each input character instead of only upon clicking somewhere? Please enter your password: <div class='form-group' :class='{"form-group_invalid": errors.has("password") && error ...

Guide to inserting .json data into a .js file

Currently, I have an HTML5 banner designed using Flash CC. However, the platform in which I am showcasing this ad does not support JSON files. I am looking for a way to transfer the information from the JSON file into either my .html or .js file so that ...

Is it more suitable for a library used by getStaticProps to be classified as a normal dependency or a dev

When working with NextJS's getStaticProps, I am implementing a library that is only utilized during build time. Should this library be categorized as a regular or development dependency in my package.json? ...

Error encountered: DataTable - Unable to retrieve the 'length' property of a null value

I am currently using a datatable in my project: function drawRadnici() { $('#tableradnici').dataTable({ "ajax": { "url": 'track_radnici.php', "type": 'POST' ...

Achieving the perfect sorting result in an array using Javascript

I am attempting to arrange the objects inside an array below in ascending order by their values and achieve the desired output as shown: var arr = [{"DOA Qty":"0.000665921017598927382910198160","LOS%":"0","FID Valid EC By Part":"0.004186044328301671376196 ...

Mapping Service by Google - Navigate from your current location to desired destination

I have a script that currently displays a route for either car or transit depending on the user's selection. I am looking to adapt this script to set the origin as the user's current location and route from there to a set latitudes and longitudes ...

The JavaScript array remains unaltered

I've got an express server set up with GET and POST routes. The initial state looks something like this: let orders = [ { sum: 0, purchases: [ { id: 1, contractId: ...

Alert Box Displays Variable Name Instead of Label Name in Form Validation - MM_validateForm()

Looking at the screenshot, you can see variable names such as "email_address", "email_message" and "email_subject". I would like these to be displayed as "Email", "Message" and "Subject" instead. The validation in this form is done using MM_validateForm() ...

Email attachments not working in Node Mailgun

I am facing an issue with my code that is designed to send emails using Mailgun in Node. The code functions as expected and sends the email successfully; however, it fails to attach the specified files. // pdfA and pdfB are both buffers defined earlier le ...

Troubleshooting Issues with Implementing JavaScript for HTML5 Canvas

I've encountered an issue with my code. After fixing a previous bug, I now have a new one where the rectangle is not being drawn on the canvas. Surprisingly, the console isn't showing any errors. Here's the snippet of code: 13. var can ...

Bringing in PeerJs to the NextJs framework

Currently delving into NextJs and working on creating an audio chat application, I've hit a roadblock while attempting to import PeerJs. An error message keeps popping up saying 'window is not defined'. import Peer from 'peerjs'; ...

Error in node.js framework due to memory allocation issue

Hello, I'm encountering an issue while running my JavaScript program. I keep getting a memory error. Can anyone help me identify the exact problem? <--- Last few GCs ---> [12908:0000015EB93DE800] 29162 ms: Mark-sweep 1396.7 (1425.2) -> 1 ...

Difficulties encountered when initiating CRA using npm start

Hi everyone! I'm dealing with a frustrating issue; every time I try to run npm start I keep encountering the error message below: events.js:288 throw er; // Unhandled 'error' event ^ Error: spawn cmd ENOENT To resolve this probl ...

Requesting the user to repeatedly input their birth year until it is less than the current year

Can anyone help me figure out how to display a prompt until the user enters a birth year that is less than the current year? I've tried using a loop in my code, but I'm having trouble getting it right. Any assistance would be greatly appreciated. ...

CustomTooltips in ChartJS allowing for an enhanced visual presentation of data

I am encountering an issue with my code where I am trying to incorporate images into custom tooltips. The goal is to dynamically generate PNG filenames based on the tooltip name or ID, but I am struggling to find unique values to assign as filenames for ea ...

Do we need to have the 'input type file' field as

I am currently working on a PHP form that includes mandatory fields for saving the data. For example: <td><input class="text_area required" type="text" name="new field" This form also has Javascript code with file upload functionality, which I ...

How can I save variable values to a text file or Excel file using Cypress.io?

Is there a way to write the values of a variable on a Text or Excel sheet? I have a variable called tex that stores string values, and I want to output these values onto text files or an Excel sheet if possible. beforeEach(() => { cy.visit('ht ...