Updating the vue data map to group items by both date and employee

I am currently facing an issue with my Vue component and template where I display employees along with their hours/scans by date. The problem is that the current mapping aggregates all hours and scans based on the first record's date.

The challenge arises because my table headers represent dates (today, tomorrow, and the day after). Therefore, I need to implement a v-if statement for each header to compare it to the corresponding record's date. This means that for employee A123, there should only be one record, whereas for employee D432, there should be two records due to different dates.

How can I incorporate the date factor into the mapping process?

Vue.config.devtools = false;
Vue.config.productionTip = false;
new Vue({
  el: "#app",
  data: {
    rows: [{
        employee: "A123",
        hours: "15",
        date: "2021-08-31",
        scans: "4"

      },
      {
        employee: "A123",
        hours: "25",
        date: "2021-08-31",
        scans: "4"

      },
      {
        employee: "D432",
        hours: "82",
        date: "2021-09-02",
        scans: "2"

      },
      {
        employee: "D432",
        hours: "40",
        date: "2021-09-01",
        scans: "5"
      }
    ]
  },
  methods: {
    groupByField(list, field) {
      const result = {};
      list.forEach(item => {
        const value = item[field];
        if (value) {
          if (!result[value]) {
            result[value] = [];
          }
          result[value].push(item);
        }
      });
      return result;
    }
  },
  computed: {
    compRows() {
      const a = this.groupByField(this.rows, 'employee');
      let b = Object.values(a)
      return b.map(item => {
        return {
          employee: item[0].employee,
          hours: item.reduce((acc, _item) => (+acc) + (+_item.hours), 0),
          scans: item.reduce((acc, _item) => (+acc) + (+_item.scans), 0),
          date: item[0].date
        }
      })
    }
  }
});
th,td{
padding:8px
}
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>


<div id="app" class="container">
  <table class="table">
    <thead>
      <tr>
        <th>Employee</th>
        <th>hours</th>
        <th>scans</th>
        <th>date</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(row, index) in compRows">
        <td>{{row.employee}}</td>
        <td>{{row.hours}}</td>
        <td>{{row.scans}}</td>
        <td>{{row.date}}</td>
      </tr>
    </tbody>
  </table>
</div>

Answer №1

To group based on employee and then on date and calculate the total of date and scans, you can use the array#reduce method.

Vue.config.devtools = false;
Vue.config.productionTip = false;
new Vue({
  el: "#app",
  data: {
    rows: [{employee: "A123", hours: "15", date: "2021-08-31", scans: "4" }, { employee: "A123", hours: "25", date: "2021-08-31", scans: "4" }, { employee: "D432", hours: "82", date: "2021-09-02", scans: "2" }, { employee: "D432",hours: "40",date: "2021-09-01",scans: "5"}]
  },
  computed: {
    compRows() {
      const grouped = this.rows.reduce((r, o) => {
        r[o.employee] ??= {};
        r[o.employee][o.date] ??= {employee: o.employee, date: o.date, scans: 0, hours: 0};
        r[o.employee][o.date].scans += +o.scans;
        r[o.employee][o.date].hours += +o.hours;
        return r;
      }, {});
      return Object.values(grouped).map(o => Object.values(o)).flat();
    }
  }
});
th,td{
padding:8px
}
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>

<div id="app" class="container">
  <table class="table">
    <thead>
      <tr>
        <th>Employee</th>
        <th>hours</th>
        <th>scans</th>
        <th>date</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(row, index) in compRows">
        <td>{{row.employee}}</td>
        <td>{{row.hours}}</td>
        <td>{{row.scans}}</td>
        <td>{{row.date}}</td>
      </tr>
    </tbody>
  </table>
</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

Executing `removeChild` within a timeout during page load does not yield the expected results

I have an HTML div that is designed to contain dynamically generated children. These children are meant to be removed from the list after a specific amount of time (e.g. 1000 ms). Although some people have experienced scope issues with timeout functions, ...

Sharing styles between ReactJS and Material-UI - best practices

I am currently facing an issue where I need to share styles across my entire web application. Here is the Problem: I have been using makeStyles in a repetitive manner as shown below: In component_A.js const useStyles = makeStyles({ specific_style: { ...

Node.js not resetting array properly

I have successfully set up a Node+Express API that is working smoothly, but I am facing an issue with returning responses for complex queries. The problem lies in the fact that the variable where I store the response data is not being reset between differe ...

The Vue transition displays properly for the "enter" state, but encounters issues with the "leave" state

Recently, I encountered an issue with a modal that is displayed on top of a semi-transparent backdrop. The appearance of both elements is controlled by the same variable using v-if. While the entry transition animation works perfectly fine, the exit trans ...

Button style not being affected by CSS

I'm having trouble changing the background color of a button in CSS. The CSS link is working perfectly fine, and the button changes color when I attempt to apply Bootstrap or use DOM to change it, but not when I use pure CSS. Here's the code sni ...

Is Formik Compatible with TextareaAutosize?

I've implemented react-textarea-autosize and formik in my project, but I'm having trouble connecting the change events of formik to TextareaAutosize. Can anyone guide me on how to do this properly? <Formik initialValues={{ ...

Issue with Vue Volar template autocomplete/intellisense when using defineComponent in VSCode

Challenge I am facing an issue with syntax highlighting and intellisense while using volar in conjunction with defineComponent. Here is what I have done: Installed TypeScript Vue Plugin (Volar) Installed Vue Language Features (Volar) Set up take over mo ...

Production environment is facing issues with Laravel API routes, although they function properly in the development environment

I have developed my frontend using Vue 3 and the backend API in Laravel. Everything works smoothly on my local system, but when deployed to production, only the web routes function correctly while the API routes return a 404 error. Both the single-page app ...

Steps for displaying an error message when incorrect credentials are entered during a login attempt

As I work on implementing a login feature, I am facing the challenge of displaying an error message when users enter incorrect login credentials. My development environment involves using the POST method within Next.js. Here is a snippet of my code: ...

JavaScript form validation eliminates input data

I recently started using the JavaScript library for client-side form validation called Bouncer. It has been working really well, but I have encountered a peculiar behavior that I need help understanding. My form has two submit buttons with different value ...

Utilizing Ajax to upload various files from separate input sources simultaneously

I want to upload multiple textual/select inputs along with two different file inputs to a PHP file using Ajax. The images from the file inputs are specific and need to be identified by their input names, so I cannot use <input type="file" multiple>. ...

In order to dismiss the popup message in the component.ts file within Angular 4, I must figure

Currently in my component.html, I have a popup message with opening and closing functionality implemented in html. However, I now need the close functionality to be moved to a method. <ng-template #content let-c="close" let-d="dismiss"> < ...

How can we prevent the continual overwriting of Object values?

I'm currently working on extracting data from the USDA Food Data Central API. Specifically, I'm interested in retrieving the "name" and "amount" values under the "nutrient" section. The excerpt below shows the information retrieved: Input- repor ...

Can you utilize the "import as" feature with just a handful of exports?

I am trying to bring in just a few exports from a module using a namespace in order to avoid adding unnecessary bulk to my project. Is there a way to achieve this? import { FaUser, FaUsers, FaScroll } as FaIcons from 'react-icons/fa'; With this ...

Do you understand why my Fabricjs canvas is rejecting a rectangle?

http://jsfiddle.net/a7ZSG/10/ check out the link to the jsfiddle for more information. Having trouble getting a red rectangle to appear in a green canvas? Can anyone figure out why it's not showing up? I've attempted using window.onload around a ...

The website is showing an error message: SCRIPT1003: This is not what I expected in Internet Explorer 11

I recently implemented Vue.js 2 in a website project, but encountered some compatibility issues with earlier versions of Internet Explorer. The specific error message received was: SCRIPT1003: Expected ':' Below is the code snippet where the i ...

An array filled with unique and non-repeating elements

I want to display random country flags next to each other, making sure they do not match. However, my specific case requires a unique solution for dealing with arrays: function displayRandomFlags() { var flagurls = ["ZPlo8tpmp/chi","cJBo8tpk6/sov","QyLo ...

Ways to retrieve text like innerText that functions across all web browsers

I need to retrieve the text from a Twitter Follow button, like on https://twitter.com/Google/followers Using document.getElementsByClassName("user-actions-follow-button js-follow-btn follow-button")[0].innerText correctly displays the text as: Follow ...

Analyzing Dynamic Content

Currently, I am engaged in content parsing and have successfully executed a sample program. To demonstrate, I have utilized a mock link which you can access below: Alternatively, you can click on this link: Click Here In the provided link, I have parsed ...

Tips for using an array as a jQuery selector in JavaScript

Managing an element with an array id id="x[]" can be tricky when it comes to dynamically changing content based on database entries. This specific element is essentially a delete button for removing table rows from the database. <div align="center" id= ...