Retrieving various properties of an object by matching IDs and displaying them without repeated reductions

I'm interested in finding a more efficient way to retrieve properties from a reduced object within a Vue component or wrapper DOM element.

Let's say I have these two data objects in my component:

player: [{
   active: true,
   id: 0,
   name: "Alfred",
   action: 0
}, {
   active: true,
   id: 1,
   name: "Bruce",
   action: 1
}],
actions: [{
   id: 0,
   label: "Give advice",
   description: "Player advises others"
}, {
   id: 1,
   label: "Fight",
   description: "Player fights enemy"
}]

...and I want to iterate through a list of options and display all results, including properties of the action associated with each player:

------------------------------------------------------------------
Active?   ID    Name     Label         Description
------------------------------------------------------------------
true      0     Alfred   Give Advice   Player advises others
true      1     Bruce    Fight         Player fights enemy

I am aware that I can loop through the players like this:

<table>
  <tr v-for="(player, index) in players" :key="index">
    <td>{{ player.active }}</td>
    <td>{{ player.id }}</td>
    <td>{{ this.getActionProp(player.action, 'label') }}</td>
    <td>{{ this.getActionProp(player.action, 'description') }}</td>
  </tr>
</table>

Using a method like this:

getActionProp(id, prop){
  return this.actions.reduce((acc, cur) => {
    return cur.id == id ? cur[prop] : acc
  }, {})
}

But it feels like it has to reduce twice for each row in the table. Is there a more optimal way to retrieve these properties, or at least reduce them only once per row?

Maybe something along the lines of:

<table>
  <tr v-for="(player, index) in players" :key="index">
    <td>{{ player.active }}</td>
    <td>{{ player.id }}</td>
    <template :action="getAction(player.action)">
      <td>{{ action.label }}</td>
      <td>{{ action.description }}</td>
    </template>
  </tr>
</table>

using getAction() as a method to perform just one reduction and return the matching action object.

Thank you for taking the time to read this, I value your insights.

Answer №1

To simplify the process, you can map out the actions in a computed function and then prepare the table rows:

Vue SFC Playground

<script setup>
import { computed, reactive } from 'vue'

const players = reactive([{
  active: true,
  id: 0,
  name: "Alfred",
  action: 0
}, {
  active: true,
  id: 1,
  name: "Bruce",
  action: 1
}])

const actions = reactive([{
  id: 0,
  label: "Give advice",
  description: "Player advises others"
}, {
  id: 1,
  label: "Fight",
  description: "Player fights enemy"
}])

const playerTable = computed(() => players.map(player => {
  return {
    ...player,
    action: actions.find(action => action.id === player.action)
  }
}))
</script>

<template>
  <h1>TEST</h1>
  <table>
    <tr v-for="player in playerTable" :key="player.id">
      <td>{{ player.active }}</td>
      <td>{{ player.id }}</td>
      <td>{{ player.action.label }}</td>
      <td>{{ player.action.description }}</td>
    </tr>
  </table>
</template>

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

Node.js and Mongoose not functioning properly in collaboration

Searching for a user based on matching first and last names. router.post('/post/user/search/tag', function (req, res) { function getRegex(_query) { return { $regex: '^' + _query + '|.*' + _query, $optio ...

What are the steps to activating components in vue.js?

Why do I always see the UsersList.vue component when opening any URL? Is it because I include it in the App.vue? If I change it to <router-view/>, I only see an empty page. How can I resolve this issue? Also, how can I navigate from ListView to Detai ...

How to remove an event listener when e.target points to a hyperlink

element, I encountered an issue using a slideshow component sourced from our components library. This component receives swipe events from a utility function that is initialized upon mounting. The problem arose while testing on a mobile phone - tapping a ...

Ways to create a smooth transition in element height without a known fixed target height

Is it possible to create a smooth height transition for an element when the target height is unknown? Replacing height: unset with height: 100px allows the animation to work, but this presents a problem as the height needs to be based on content and may v ...

Unable to trigger click event on dynamically added element using Chrome (jQuery)

My approach here involves dynamically creating a drop-down and binding the click event to the <option> within the <select> var $select = $('<select></select>'), $option1 = $('<option>a</option>') ...

Is there a way to easily access the automated departure range feature of a date

I apologize if my question seems too simple, but I am having trouble understanding JavaScript. My issue pertains to a range datepicker where I want the departure picker to automatically open when the arrival is selected. Here's the JavaScript code I h ...

Understanding the error handling in Express.js

Learning about error handling in express is new to me and I have a straightforward piece of code like this - const express = require('express'); const MongoClient = require('mongodb').MongoClient; const app = express(); let url = &a ...

Shift content from side to side with a click

I've been attempting to shift content left and right using an onclick event and I need it to stop at the margins on the left or right. The list-items are generated dynamically. Here's the code I've tried so far, but it's not quite worki ...

How can I incorporate multiple JSX files into plain HTML without using npm?

I have a question regarding importing JSX files in an HTML file without using npm and directly running it with LiveServer. I have two files, index.js and app.jsx, that I want to connect within my index.html script. How can I achieve this? Code: index.html ...

The jQuery remove function will only take effect on the second click following an AJAX request

I'm facing an issue with my jQuery code where two divs contain lists of links, triggering AJAX calls to append JSON data to a separate div. Upon clicking a link, the corresponding link div should hide. There's also a third div with the class "pan ...

When implementing ReplaySubject in Angular for a PUT request, the issue of data loss arises

I seem to be encountering a problem with the ReplaySubject. I can't quite pinpoint what I've done wrong, but the issue is that whenever I make a change and save it in the backend, the ReplaySubject fetches new data but fails to display it on the ...

Resolving the issue of nested modals within Bootstrap

I am experiencing some issues with my customer visits list page. When I try to add a visit, it opens a bootstrap popup ("#Pop1") to record the visit details. Within this modal, there is an option to add a new customer on the spot, which then triggers anoth ...

Preventing page navigation in JavaScript: Why it's so challenging

I am encountering an issue with a link element that I have bound a click event to (specifically, all links of a certain class). Below is an example of the link element in question: <a id="2" class="paginationclick" style="cursor: pointer;" href=""> ...

"Divs are now linked and drag as one cohesive unit instead of

As I was experimenting with making images draggable and resizable, I encountered a small issue. When I attempted to drag two or more images, they would merge into one large draggable object instead of remaining separate. My goal was to make each image drag ...

Implement rotation in Three.js that mirrors the functionality of Blender

Is there a way to permanently change the default rotation of a mesh in three.js after it has been loaded? For example, if I load a mesh with a rotation of 0,0,0, can I then rotate it 90 degrees on the X axis and set this new rotation as 0,0,0? It's i ...

Bring in JavaScript files on a global scale in Vue.js 3

Hello, I am facing an issue while trying to import jQuery and THREEJS globally into my Vue.js cli project. Whenever I attempt to import them into my .vue file (like home.vue), I encounter the following error: 'import' and 'export' ma ...

Encountering a node globby error when implementing multiple patterns

Currently, I am successfully using node glob for folder1 as shown below: glob('folder1/*.js'), function(err, files){ if (err) { console.log('Not able to get files from folder: ', err); } else { files.forEach(function (file) ...

What could be causing the errors in my subscription function?

Working on an e-commerce website, I encountered errors in the "cartservice" specifically in the "checkoutFromCart()" function. The console displayed the following error: src/app/services/cart.service.ts:218:81 218 this.http.post(${this.serverUrl}ord ...

Manually close the AntD Menu without using any shortcuts

I'm facing a unique situation with my table implemented using antd. Each row has a dropdown menu that opens a modal upon clicking. To ensure the dropdown menu doesn't trigger the row click event, I used stopPropagation on the menu item click. Eve ...

Inaccurate audio timestamps in Chrome

I am currently working on a web application that features an audio component sourced from a local .mp3 file lasting approximately 1 hour. I have encountered an issue where, upon clicking the seekbar to jump to a specific point in the audio (e.g., 00:01:00) ...