Keeping related items organized in Vue

I'm a newcomer to Vue and have carefully studied the documentation for Vue and Vuex. However, I am currently facing an issue which is hindering my progress. Although I believe I can figure it out eventually, I want to approach it with clean and best practices in mind.

The Scenario: - I have entities - I have users - An entity can belong to multiple users

What I aim to achieve is to display a list of all users where those assigned to the entity are checked.

My Vuex store looks like this:

export default new Vuex.Store({
    state: {
        users: [],
        entities: []
    },
    getters: {
        USERS: state => state.users,
        ENTITIES: state => state.entities,
        ENTITY: state => id => {
            return state.entities.find(entity => entity.id == id)
        }
    },
    mutations: {
        SET_USERS: (state, payload) => {
            state.users = payload
        },
        SET_ENTITIES: (state, payload) => {
            state.entities = payload
        },
        UPDATE_DEVICE: (state, payload) => {
            state.entities = state.entities.map(entity => {
                if(entity.id === payload.id){
                    return Object.assign({}, entity, payload.data)
                }
                return entity
            })
        }
    },
    actions: {
        GET_USERS: async (context) => {
            let { data } = await Axios.get('/api/v1/users')
            context.commit('SET_USERS', data)
        },
        GET_ENTITIES: async (context) => {
            let { data } = await Axios.get('/api/v1/entities')
            context.commit('SET_ENTITIES', data)
        },
        UPDATE_ENTITY: ({commit}, payload) => {
            Axios.put('/api/v1/entities/' + payload.id + '/', payload.data).then((response) => {
                commit('UPDATE_ENTITY', payload)
            });
        }
    }
})

My Entity Component fetches the users from the store using the created hook. The entity's data is retrieved from the store through the computed property entity(). Similarly, the list of all users is served by the computed property users().

created(){
   if(!this.$store.getters.USERS.length) this.$store.dispatch('GET_USERS')
},
computed: {
   entity(){
      const entityId = this.$route.params.id
      return this.$store.getters.ENTITY(entityId)
   },
   users(){
      return this.$store.getters.USERS
   }
}

In the template, I display all users along with a checkbox:

<ul>
   <li v-for="(user, i) in users" :key="i">
      <input type="checkbox" :value="user" :id="'user_'+i" :name="'user_'+i" v-model="???" />
      <label :for="'user_'+i">{{user.name}}</label>
   </li>
</ul>

Additionally, within the same component's template, I have a second list displaying all users belonging to the entity. This list should be kept in sync with the 'selectable list'. Therefore, all users with checked checkboxes should also be listed in this section:

<ul>
   <li v-for="user in entity.users" :key="user.id">
      {{user.name}}
    </li>
</ul>

My current roadblock lies in determining whether to use a computed property for device.users, incorporating get() and set(), and utilizing it as v-model on the checkboxes. I attempted this approach but encountered issues since the user objects in the all-users list did not match the objects in the device.users list, despite representing the same users. At this point, I feel that I might be making the process more complex than necessary and potentially overlooking a more conventional Vue solution.

To cut the long story short, what would be the optimal way to tackle this task? I believe it's a fairly common challenge in Vue.

Thank you for any guidance provided, and if more code or details are needed, I will gladly supply them!

Answer №1

What is the structure of an entity like? If there is an array called 'users' within it, you can determine the checkbox value by implementing a simple JavaScript function that checks if the user's unique ID is included in the list for that specific entity.

To avoid recalculating the same array for each element in a v-for loop, create a new property in computed:

userIdsWithEntity() {
  if (!this.entity) return []; // Make sure to handle cases where the entity hasn't been initialized yet
  return this.entity.users.map(x => x.id)
}

Next, set up a straightforward function for the checkbox value to return either true or false:

:value="userIdsWithEntity.includes(user.id)"

Instead of using v-model (which combines :value and @input/@change to update the property defined in :value, potentially causing conflicts with your :value declaration), utilize @change to manage toggling the checkbox. This involves dispatching an action to Vuex to add/remove the user from the entity when necessary.

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

Struggling to make Datatables function properly with basic JSON data

As a newcomer to frontend development, I'm attempting to convert a JSON call into a table format. After researching, it seems like datatables is the best tool for this task. However, I'm struggling to make it work. Here is my JSON GET call: GET ...

Transforming jQuery into Angular - Press Button to update choices in Dropdown List

I am looking to integrate some AngularJS features into a website that currently utilizes jQuery. Here is the issue I am facing: With jQuery, clicking a button triggers a dropdown item change. Please refer to the jsfiddle below for an example: $('# ...

"Interactive jQuery feature allows users to edit table content live with the ability to update and delete data via

I am working on implementing live editing, updating, and deleting functionality in a table using jQuery. However, I have encountered two problems: When clicking the pen icon from order #3 to #1, it requires 3 clicks, but when clicking from order #1 to ...

Sending files correctly using Node.js

Here is a simple middleware to consider: (req, res, next) => { const stream = fs.createReadStream(req.filePath) await new Promise((resolve, reject) => stream .on('error', reject) .on('end', resolve) .pipe(res ...

Inconsistencies in Height Among JQuery Elements

I am encountering an issue with my datatable.js, where I am attempting to limit its height based on a specific row number, such as 4.5 rows. However, I am facing a problem with the row height (tr height). For example, when using the following method with m ...

Interactive feature in Three.js causes page to scroll downwards upon object selection

Exploring Three.js for the first time, I'm looking to integrate it into the landing page of my website. However, I've encountered an issue where clicking on the scene area with my object causes the page to shift downward. I've tried adding o ...

Are you looking for a way to prevent the default behavior of an event in angular-ui-router 1.0.x? Check out

Recently, I made a change in my code where I replaced $stateChangeStart with $transitions.onStart $rootScope.$on('$stateChangeStart', function(e, ...){ e.preventDefault(); // other code goes here... }); Now, the updated code looks lik ...

Display data in an HTML table using PHP and AJAX within a single file

My project involves using PHP to populate an HTML table with random numbers upon page load. What I'm aiming to achieve is the ability to click a button and have the table populated with new numbers by invoking PHP through an ajax request. The challeng ...

Prevent the border from shrinking upon being clicked

I'm currently working on customizing an accordion using jQuery for the animation effects. However, I am facing an issue where clicking on the accordion header causes the border around the plus sign to shrink in size as well. My goal is to only have th ...

What causes my ready function to consistently execute upon controller or directive reinitialization?

Every time my controller or directive reinisilize, the angular.element(document).ready(function(){...}); function is executed. Why does this happen? In my scenario, I have two controllers and one directive. I update a value in the parent controller which ...

Encountering a registration error persistently: [TypeError: Network request failed]

Currently, I am in the process of developing an application using React for the frontend and node.js for the backend. However, I have encountered a persistent network error whenever I try to sign up or log in. What puzzles me is that when I test the API en ...

Utilizing Node.js, Socket.io, and P5.js to generate an interactive live video feed

I am attempting to set up a basic video stream on my local network. However, the current code is triggering the following error message: Uncaught TypeError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided val ...

The deletion request using the form in Express is experiencing issues and not functioning properly

When attempting to delete data from a database using a form in node.js and express, I am encountering issues with the deletion process. It seems that there are only two methods available - get and post - and no specific delete method. router.js code rout ...

Launching the server with a custom path in Nuxt.js: Step-by-step guide

My Nuxt.js application has several nested routes. . ├── index │   ├── _choice │   │   ├── city │   │   │   ├── index.vue │   │   │   ├── _zipCode │   │   │   │   ├── i ...

`Angular project not responding to HTML mouse click event`

I am a beginner with the Angular framework and currently experimenting with creating a basic button in the app.components.html file. My goal is to have this button trigger a function declared in the app.component.ts file. Initially, I used the (click) even ...

Having trouble reaching external methods in Vue with Echarts OnClick Methods?

Hey there! I've been working on integrating Echarts into a Vue application, and I've encountered a bit of a roadblock. Specifically, I'm trying to capture the item clicked on one of the charts and then pass that data back to the parent compo ...

Error message encountered in Express.js when trying to apply the ejs function: "View is not a constructor"

I am attempting to execute certain tasks before the original app.get function is called. After referring to this page, I applied their method which worked for the most part, except when using a rendering engine. The code snippet below demonstrates what I ...

arrange data based on table heading using vue.js

I've recently upgraded to Vue 2.x and found out that the orderby directive is no longer supported as per this documentation. I'm trying to avoid adding another JavaScript library, but if using lodash is the only option, I'm willing to give ...

In JavaScript, numbers cannot begin with a zero

var number = 05000; var addNumber = 1; When I try to add number + addNumber, the result seems to be incorrect. var total = number + addNumber; // the result is 20481 Refer to the image below for the quick watch result: https://i.sstatic.net/Hwz84.png ...

Ways to avoid data looping in jQuery Ajax requests

This is in relation to the assignment of multiple users using the Select2 plugin, Ajax, and API. The situation involves a function that contains 2 Ajax calls with different URLs. Currently, there are pre-selected users stored in the database. The selection ...