Looping through data in Vue.js with a specific condition

There is an object structured like this:

groupedContacts:

{
  4: [
      {name: 'foo'},
      {name: 'bar'}
    ],
  6: [
      {name: 'foo bar'},
    ]
}

Additionally, we have another array:

companyList.models:

models: [
  {id:4, name: 'company A'},
  {id:6, name: 'company B'},
]

The IDs in the companies correspond to keys in groupedContacts. One array contains company names and the other includes contact details for these companies.

The goal is to display them in multiple tables like so:

Table 1
Company A (id4)
- foo
- bar 

Table2 
Company B (id6)
- foo bar

Despite the following code, there are no errors but the tables do not show any contacts:

<div
    v-for="(company, key) in companyList.models"
    :key="key"
    class="table table--hover mt-4"
>
  <h4 class="mb-4" v-html="company.name" />
  <table>
    <thead>
      <tr>
        <th class="text-left" v-html="__t('name')" />
      </tr>
    </thead>
    <tbody
      v-for="(groupContacts, key) in groupedContacts"
      :key="key"
      v-if="company.id === key"
    >
      <tr
        v-for="(contact, contactKey) in groupContacts"
        :key="contactKey"
      >
        <td v-html="contact.name" />
      </tr>
    </tbody>
  </table>
</div>

View the result achieved in the browser by clicking on this link.

Answer №1

A suggestion is to utilize a computed property named companies in the following manner:

 computed: {
        companies() {

          return this.models.map(c => {
            c.groups = this.groupContacts[c.id];
            return c;
          })
        }

      }

After that, you can iterate through it like so:

 <div v-for="(company, key) in companies" :key="key" class="table table--hover mt-4">
          <h4 class="mb-4">{{company.name}}</h4>

          <table>
            <thead>
              <tr>
                <th class="text-left">Name</th>

              </tr>
            </thead>
            <tbody>
              <tr v-for="(contact, contactKey) in company.groups" :key="contactKey">
                <td> {{contact.name}}</td>
              </tr>
            </tbody>
          </table>
        </div>

new Vue({
  el: '#app',

  data() {

    return {
      groupContacts:

      {
        4: [{
            name: 'foo'
          },
          {
            name: 'bar'
          }
        ],
        6: [{
          name: 'foo bar'
        }, ]
      },
      models: [{
          id: 4,
          name: 'company A'
        },
        {
          id: 6,
          name: 'company B'
        },
      ]
    }
  },
  computed: {
    companies() {

      return this.models.map(c => {
        c.groups = this.groupContacts[c.id];
        return c;
      })
    }

  }
})
<body>
  <div id="app">

    <div v-for="(company, key) in companies" :key="key" class="table table--hover mt-4">
      <h4 class="mb-4">{{company.name}}</h4>

      <table>
        <thead>
          <tr>
            <th class="text-left">Name</th>

          </tr>
        </thead>
        <tbody>
          <tr v-for="(contact, contactKey) in company.groups" :key="contactKey">
            <td> {{contact.name}}</td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="1563607055273b6d">[email protected]</a>/dist/vue.js"></script>

Answer №2

Avoid combining v-if with v-for, as recommended in the Vue.js documentation (Vue.js docs).

Instead of mixing them, consider using a computed property following the suggestion from the documentation:

<template>
  <div>
    <div v-for="(company, i) in companyContacts" :key="`company_${i}`" class="table table--hover mt-4">
      <h4 class="mb-4" v-html="company.name" />
      <table>
        <thead>
          <tr>
            <th class="text-left" v-html="__t('name')" />
          </tr>
        </thead>
        <tbody>
          <tr v-for="(contact, j) in company.contacts" :key="`company_${i}_contact_${j}`">
            <td v-html="contact.name" />
          </tr>
        </tbody>
      </table>
    </div>
  </div>
</template>
<script>
export default {
  computed: {
    companyContacts() {
      return this.companyList.models.map(model => {
        model.contacts = this.groupedContacts[model.id]
        return model
      })
    }
  },
  data: () => {
    groupedContacts: {
      4: [{
          name: 'foo'
        },
        {
          name: 'bar'
        }
      ],
      6: [{
        name: 'foo bar'
      }, ]
    },
    companyList: {
      models: [{
          id: 4,
          name: 'company A'
        },
        {
          id: 6,
          name: 'company B'
        },
      ]
    }
  }
}
</script>

I trust this information proves useful!

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

Creating a dropdown menu in Vue 3: A step-by-step guide

I've scoured the entire internet, but I still can't seem to resolve this issue. When using the code below, I keep getting an error message that says 'Uncaught ReferenceError: VueSelect is not defined.' Can you help me figure out what&ap ...

The React Material-UI Slider does not move when OnChangeCommitted is triggered

Struggling with implementing the Material UI slider in React, I encountered an issue where the OnChange function would trigger every time the value changed. I needed it to activate only when the left mouse button was released. Fortunately, I discovered a s ...

Component does not detect change when the same number is sent as input

Let me paint you a picture: I have this nifty component, set up with the OnPush strategy, that showcases a PDF document, sliding through pages one by one, and granting users the ability to smoothly glide through pages and jump to specific ones. It even of ...

Instructions on how to showcase a standard text within a designated text container

I am currently facing an issue with a textarea or textbox that is dynamically receiving URLs from a database. The textbox is displaying the full URL address, which is not visually appealing. I would like to replace this with some generic text such as "cl ...

Instructions on creating a countdown timer that reveals a hidden div once it reaches zero, remains visible for a set period, and then resets

I created a countdown timer that displays a div when the timer reaches zero. However, I am struggling with getting the timer to reset and start counting down again after displaying the div. For instance, if I set the timer for 7 days and it reaches the de ...

Error encountered while attempting to render a form within a partial in Rails 5: "simple_fields_for" method is not defined for the SimpleForm::FormBuilder instance

This is a continuation from this thread: Passing a form as a local to a ajax rendered partial in Rails 5 I've searched extensively but haven't been able to find a working solution. Relevant Controller (profits_controller.rb): def new_tabs ...

JavaScript: CryptoJS does not have the SHA1 method implemented

This seems like a simple issue to resolve.... Although my CryptoJS object is present, it appears to be lacking a SHA1 method. What steps should I take to rectify this? Despite various examples available, my specific case remains unresolved... On a posit ...

In Vue, a computed property is rendered as regular text on the screen

Is there a way to format the title using HTML spans instead of plain text? Here is the code: spanTitle() { return this.title.replace(/([A-Za-z0-9'<>/]+)/g, '<span>$1</span>'); } {{ spanTitle }} this.title = "Upc ...

Tips for querying MongoDB schemas that reference other schemas in the field?

Looking to search for a product by its name within the DOC Schema. However, the products are stored as references in another Product Schema with the _id. Below you can find the code snippets to understand the structure: DOC Schema import mongoose from &qu ...

Having trouble with Electron nodeIntegration functionality and experiencing some odd behavior in general with Electron

Having just started working with Electron, I find myself encountering some puzzling behavior that has me stumped. Here's a quick summary of the issue: I am unable to establish communication between Electron and the HTML "Uncaught ReferenceError ...

How can I display Vue object properties in the header section?

I have a table displaying various properties of people. In anticipation of future extensions to these properties, I want to list all available properties in the table header and provide corresponding answers in the table body. To access a person's pr ...

Guide to altering the color of a list item when hovering in HTML

Is there a way to change the color of the <li> element only when hovering over it, without affecting its parent or child elements? Here is an example: HTML: <div id="tree"> <ul> <li>apple</li> <li>banana</l ...

Notifying asynchronous completion using Gulp, Babel, and configuration file config.yml

My current project involves using babel and gulp for handling tasks, as well as loading a yml config file for paths. This is the content of cofing.yml: PATHS: # Path to source folder sources: "jet/static/jet_src" # Path to dist folder dist: "jet/ ...

What are the steps to resolve the npm error message "npm ERR! code ELIFECYCLE"?

Whenever I attempt to launch npm run serve for my vue live server, an error occurs. Can anyone explain why this is happening? error code ELIFECYCLE error errno 1 error <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c6a3bea7ab ...

Saving an image and form data together in local storage can be accomplished by using JavaScript

Is there a way to save an image to local storage along with form data? I would like to store the form data in a database and keep the image in local storage. Any help would be greatly appreciated. Thank you! <form id="saveImageForm"><input type ...

What content appears post-iframe?

After researching for a while, I've only come across information about text displayed after a broken iframe on this topic. However, what I actually want to do is display text below an iframe set at 90% height, like so: I would like to add some text i ...

FullCalendar Angular 10 not displaying correct initial view

I am currently using Angular 10 along with FullCalendar version 5.3.1., and I am facing an issue where I cannot set the initial view of FullCalendar to day view. It seems to be stuck on the dayGridMonth view by default. Below is the HTML snippet: <full ...

Implementing a dynamic navigation bar that expands and collapses on mouse hover in a React application

I have a side navigation bar on my webpage that I obtained from a React Bootstrap website, so the class names are already pre-loaded. Instead of using a toggle hamburger icon to expand or collapse the navigation, I want to achieve this functionality based ...

Three.js - Model is unable to cast shadows

Greetings! I am currently diving into the world of three.js and utilizing react-three-fiber to integrate it with React. However, I've encountered a challenge regarding shadow casting between models. Despite setting obj.castShadow = true and obj.receiv ...

IE8 triggers automatic download upon receiving JSON response using jQuery

Can you help me make IE8 compatible with this code using jQuery to handle an ajax request that returns data as JSON? $.ajax({ url: formAction, type: 'post', dataType: 'json', data: form, success: ...