Search code examples
javascripthtmlvue.jsvuex

use vuex mapGetters to iterate in a state obj of users


i am learning vuex at the moment and i am stuck on the mapping functionality like import { mapGetters } from 'vuex'; in my state i have a object called users where i save user data and later will add an addNewUser functionality to expand the object of users. But for this test case i just created a dummy user named "John":

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    users: [
      {
        userName: 'John',
        income: 2000,
        leftover: 0
      }
    ]
  },
  getters: {
    user: state => {
      return state.users;
    },
  },
  mutations: {},
  actions: {
    addNewUser(userName, income) {
      console.log(userName, income, 'from vuex');

    }
  },
  modules: {}
});

before i gone this way i simple called john with a this.$store.state.users and then iterated over the userNames with an forEach. But figured out this isn't the best way to do that.

how can i achieve to get the state data of users, and print them out in like a forEach loop as i did before?

In Line 129 loadAllUsers() you can see my old way to achieve this:

<template>
  <div
    id="user-modal"
    class="modal fade"
    tabindex="-1"
    role="dialog"
    aria-hidden="true"
  >
    <div
      class="modal-dialog modal-dialog-centered"
      role="document"
    >
      <div class="modal-content">
        <div class="modal-header">
          <h5 class="modal-title">
            Settings
          </h5>
          <button
            type="button"
            class="close"
            data-dismiss="modal"
            aria-label="Close"
          >
            <span aria-hidden="true">&times;</span>
          </button>
        </div>
        <div class="modal-body">
          <!-- List all Users -->
          <div
            id="users-list"
            class="mb-3"
          >
            <h5>Users:</h5>
            <ul class="list-group">
              <li
                v-for="user in userList"
                :key="user.userName"
                class="list-group-item"
              >
                {{ user.userName }}
              </li>
            </ul>
          </div>

          <!-- Add New Users -->
          <h5>Add New User:</h5>
          <div class="input-group mb-1">
            <div class="input-group-prepend">
              <span
                id="basic-addon1"
                class="input-group-text"
              >
                <i class="fas fa-user" />
              </span>
            </div>
            <input
              v-model="userNameInput"
              type="text"
              class="form-control"
              placeholder="Username"
            >
          </div>

          <div class="input-group">
            <div class="input-group-prepend">
              <span
                id="basic-addon1"
                class="input-group-text"
              >
                <i class="far fa-money-bill-alt" />
              </span>
            </div>
            <input
              v-model="userIncomeInput"
              type="number"
              class="form-control"
              placeholder="Income"
            >
          </div>
        </div>
        <div class="modal-footer">
          <button
            type="button"
            class="btn btn-secondary"
            data-dismiss="modal"
          >
            Close
          </button>
          <button
            type="button"
            class="btn btn-primary"
            @click="createNewUser"
          >
            Save changes
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { mapGetters } from 'vuex';
// import { mapActions } from 'vuex';
export default {
  data() {
    return {
      userNameInput: '',
      userIncomeInput: '',
      userList: []
    };
  },
  computed: {
    ...mapGetters(['user']),
    printUserTest(user) {
      return user;
    }
  },
  created: function() {
    this.loadAllUsers();
  },
  methods: {
    // ...mapActions({
    //   addNewUser: 'addNewUser'
    // }),
    loadAllUsers() {
      let allUsers = this.$store.state.users;
      allUsers.forEach(user => {
        this.userList.push({ userName: user.userName });
      });
      // },
      // createNewUser() {
      //   let userName = this.userNameInput;
      //   let userIncome = this.userIncomeInput;
      //   console.log(userName, userIncome);
      // }
    }
  }
};
</script>

<style lang="scss">
#user-modal {
  color: $black;
  .input-group-text {
    width: 46px;
  }
}
</style>

Solution

  • With you can mapGetters you can map the users in your store to a computed. that will be reactive.

    So you dont even need to load the users.

    Vue.config.devtools = false;
    Vue.config.productionTip = false;
    
    const store = new Vuex.Store({
      state: {
        users: [{
          userName: 'John',
          income: 2000,
          leftover: 0
        }]
      },
      getters: {
        users: state => {
          return state.users;
        },
      }
    })
    
    
    var app = new Vue({
      el: '#app',
      store,
      computed: {
        ...Vuex.mapGetters(["users"]),
      }
    })
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <script src="https://unpkg.com/[email protected]/dist/vuex.js"></script>
    
    <div id="app">
      <div v-for="user in users">
        {{ user.userName }}
      </div>
    </div>
    
    <div>

    https://vuex.vuejs.org/guide/getters.html#getters