Utilizing a V-for/V-if loop to iterate through a multi-dimensional array and filter data based on date

I'm facing a challenge with setting up a v-for loop for an array I've constructed, which is already in the desired format

Below is a snippet representing the data format. Essentially, I want to create a table for employees where the header consists of dates and the employee data is aligned with the respective date.

The problem lies in my inability to navigate down to the jobs level and pair the data for each table cell with the corresponding date in the header

Based on the array dumped below, I am looking for something like this:

Employee  |  08/12/2021            |  08/13/2021
----------------------------------------------------------------
Miranda   | Area 1234567           |  Area 1234569
              Job 123 - 10 Hours        Job 184 - 18 Hours
            Area 1234568
              Job 167 - 15 Hours

Essentially, it involves matching the array records by employee and date (in the table header) and displaying the area/job information in the table cell where there's a match

How can I adjust the existing v-for loop structure I've initiated to achieve this?

const nest = (rows) =>
  rows .reduce(
    (a, row) => {
      const employee = a [row .employee] || (a [row .employee] = {dates: {}})
      const date = employee .dates [row .job_date] || (employee .dates [row .job_date] = {areas: {}})
      const order = date .areas [row .area_number] || (date .areas [row .area_number] = {jobs: {}})
      const job = order .jobs [row .job] || (order .jobs [row .job] = {hours: '', scans: '', job_date: ''})

      job.hours += row.hours
      job.scans += row.scans
      job.job_date = row.job_date

      return a
    },
    {}
  );

new Vue({
  el: "#app",
  props: { 

  },
  data: {
    rows: [
        {  
            employee: "Miranda",
            job: "123",
            hours: "10",
            job_date: "08/12/2021",
            scans: 37,
            area_number: "1234567",

        },
         {  
            employee: "Miranda",
            job: "167",
            hours: "15",
            scans: 12,
            job_date: "08/12/2021",
            area_number: "1234568",
            
        },
        {  
            employee: "Miranda",
            job: "184",
            hours: "18",
            scans: 24,
            job_date: "08/13/2021",
            area_number: "1234569",
            
        }
    ],
},
computed: {

    numbersByEmployee() { 
      return nest(this.rows)
    },
    dates() {
      const dates = [...new Set(this.rows.map(r => r.job_date))]
      return dates.sort((a,b) => new Date(a) - new Date(b))
    },
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>


<div id="app">

  <table>
  <thead>
      <tr>
       <th>Employee</th>
          <th v-for="date in dates" :key="date">{{ date }}</th>
      </tr>
    </thead>
  <tbody>
    <tr v-for="(areas,employee) in numbersByEmployee" :key="employee">
      <td>{{employee}}</td>
      <td v-for="date in dates" :key="date">
        
      </td>
    </tr>
  </tbody>
  </table>


{{numbersByEmployee}}
</div>

Answer №1

Similar to arrays, the v-for directive can also be applied to objects. Learn More

Syntax

v-for="(value, key) in object"

Implementation Example

const organizeData = (rows) =>
  rows.reduce(
    (result, row) => {
      const employee = result[row.employee] || (result[row.employee] = { dates: {} })
      const date = employee.dates[row.job_date] || (employee.dates[row.job_date] = { areas: {} })
      const order = date.areas[row.area_number] || (date.areas[row.area_number] = { jobs: {} })
      const job = order.jobs[row.job] || (order.jobs[row.job] = { hours: '', scans: '', job_date: '' })

      job.hours += row.hours
      job.scans += row.scans
      job.job_date = row.job_date

      return result
    },
    {}
  );

new Vue({
  el: "#app",
  props: {

  },
  data: {
    rows: [
      {
        employee: "Miranda",
        job: "123",
        hours: "10",
        job_date: "08/12/2021",
        scans: 37,
        area_number: "1234567",

      },
      {
        employee: "Miranda",
        job: "167",
        hours: "15",
        scans: 12,
        job_date: "08/12/2021",
        area_number: "1234568",

      },
      {
        employee: "Miranda",
        job: "184",
        hours: "18",
        scans: 24,
        job_date: "08/13/2021",
        area_number: "1234569",

      }
    ],
  },
  computed: {

    organizedDataByEmployee() {
      return organizeData(this.rows)
    },
    distinctDates() {
      const datesList = [...new Set(this.rows.map(r => r.job_date))]
      return datesList.sort((a, b) => new Date(a) - new Date(b))
    },
  }
});
td,
th {
  border: 1px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <table>
    <thead>
      <tr>
        <th>Employee</th>
        <th v-for="date in distinctDates" :key="date">{{ date }}</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(dataObj, name) in organizedDataByEmployee" :key="name">
        <!-- name will be Miranda-->
        <!-- Value will be dates object-->
        <td>{{name}}</td>
        <td v-for="(individualDateData, dateValue) in dataObj.dates" :key="dateValue">
          <div v-for="(areaCollection, areaKey) in individualDateData">
            <div v-for="(specificArea, areaId) in areaCollection">
              Area {{ areaId }}
              <div v-for="(jobDetails, jobId) in specificArea.jobs">
                Job ID: {{ jobId }} - Hours Worked: {{jobDetails.hours}}
              </div>
            </div>
          </div>
        </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

I encountered difficulty in assigning a JSON response to a variable, both with and without using JSON.parse()

I'm in the process of creating a website that, among other things (and crucially for this particular issue), stores your current location data in a variable by fetching it from the ipinfo API (https://ipinfo.io/json) After encountering the problem of ...

Generate a fresh array using the data from the existing array object

I have nested objects within arrays that I need to manipulate. { "page": [ { "num": "1", "comp": [ { "foo": "bar", "bar": "foo", ...

Need help: Autocomplete feature not working for two fields

I am currently working on implementing an autocomplete feature on two textboxes. The idea is that when a value is selected in one of the textboxes, another value should automatically appear in the other textbox. To better illustrate this concept, let me pr ...

What is the process for encrypting a string in JavaScript?

Is there a simple way to hash a string in JavaScript without having to create the hashing algorithm myself? Are there any reliable npm packages or built-in functions available for this task? If so, how can I utilize them to hash a string? For instance, if ...

The dangers posed by vulnerabilities in the React library

Hi there, I just finished setting up react-redux and noticed some vulnerabilities showing up in my console - both low and high. Can anyone explain what this means and if I should consider uninstalling it? ...

What is the method to retrieve the information from a JSON response of a POST request in a Next/React application?

I am currently leveraging the Next.js API route to manage a POST request and subsequently send a response back to the frontend. To verify this process, I have utilized the Rapid API client extension and confirmed that a response is indeed being sent to the ...

Is there a way to add text to HTML code using CKEditor?

I incorporate CKEditor into my website. When I click on a specific link, it adds some text to the editor successfully. However, when I switch to the source tab, I am unable to append this text to the existing source code. Can anyone offer guidance on h ...

Unexpected trigger of Vue function with parameters from child component

I am encountering an issue with the following component: <template> <button class="button" @[click]="action">{{ text }}</button> </template> <script> export default { name: "Button", props: ...

Searching for a specific element in jQuery by querying a string

I have a situation where an ajax request is made to send text using the POST method to another PHP page. This PHP page then converts the text into markdown format and sends it back. Here's an example of what it looks like: "<p>Meep, meep, <e ...

Remove any objects from the array that have empty values when filtered

I am facing a challenge with filtering objects in an array. Each object contains a title and rows, where the rows also have a risk value (like P1, P2, P3, etc.). My goal is to extract only the rows that have a risk equal to P1 while skipping any objects th ...

Declaring a Javascript variable within an if statement does not alter the value of the global variable

Currently, I am working on enhancing my HTML projects by using JavaScript to modify the video source. Below is the video element in question. <div> <video id="songVid" onmouseover="controlsVid()"> <source src=&qu ...

Perform time update every second

Is it feasible to have my timeupdate function run every second? (Using VUE CLI) @timeupdate="videoSecond" videoSecond(){ let Second = this.player.currentTime(); let CaptureList = this.capturesList; CaptureList.forEach(element => ...

The transition property in CSS and JavaScript does not seem to be functioning properly in Firefox

Recently, I integrated a Slide in menu script on my website using a Slide in menu script. After following all the instructions provided, the menu started working flawlessly on Chrome and Safari browsers. However, my main goal was to make it function on Fir ...

Issue with Angular: no action taken when re-calling function and utilizing the

In one of my components, I am using route parameters to switch between different "tabs". Whenever I switch tabs, I call a function specific to that tab which is subscribed to the route parameters. Here is an example of one of those functions: getUserFeed( ...

Using props as classnames in next.js applications

I am currently attempting to create a dynamic header for each page of my app that changes color based on the current page. Here is my approach: <Header className="headerBitcoin"></Header> My goal is to have the same header component ...

How can a regular number be used to create an instance of BigInteger in jsbn.js?

I attempted both methods: const num1 = new BigNumber(5); And const num2 = new BigNumber(7, 10); However, I encountered the following error: Error: 'undefined' is not an object (evaluating 'num2.nextBytes') bnpFromNumberjsbn2.js:126 ...

Using parameters in Vue router

Having some trouble here. Can't seem to make it work. I've got this component called Project. Inside, there's this block of code: When I click on project, I want it to navigate to another detail page but nothing happens: {path: '/det ...

Styling elements with CSS

I've been attempting to align a button to the right of another button. The example above illustrates what I'm trying to achieve. I used Bootstrap to build it, which has a useful navbar feature for layout. However, despite my efforts to use right ...

Utilizing onClick with material-ui button - functioning flawlessly for a single interaction

I have been attempting to encapsulate a Material-UI button within another component. Everything seems to be working well, except for when I try to handle the onClick event - it appears to only work once. Here is an example that demonstrates the issue: ht ...

Enhancing the mobile menu with a feature that allows users to easily close the

I am currently designing a mobile menu for a website that I created using Wordpress with the Divi Theme. When the user clicks on a "hamburger icon", it triggers a fullscreen menu to open: mobile menu If you tap on "Termine", it will reveal a submenu: mo ...