# Add New Store and Service Modules

# Step 1: Create a Service

  • We will make an amenities service. We can add POST/PUT/GET requests into this service, as it will govern the amenities HTTP requests and any necessary logic. For now, we'll add a GET method.
  • We will use a request-config already defined to conduct this action.
  • You can create request-configs to make HTTP requests easier.
  • Request configs are purely convenience, but must be derived from src/request-configs/base-request.ts
  • See other files in the src/request-configs.ts file for examples.

/src/services/amenities.ts


import { adminRequest } from '../request-configs/admin-request';

export const getAmenities = () => adminRequest.get(`/property-api/amenities`);

export default {
  getAmenities,
};

# Step 2: Create a Store Module to Call the Service and Set State

/src/store/modules/amenities.ts

import { ActionContext } from 'vuex';
import amenities from '@/services/amenities';

export default {
  // We can call this module from the store using an `amenities` namespace.
  namespaced: true, // 'amenities/'

  // Our state that will be set in MUTATIONS and retrieved from using GETTERS 
  state: {
    list: undefined,
  },
  // Use GETTERS to expose state to the UI.
  getters: {
    list(state: any): any[] {
      // Using our `list` state, we will get the `data` object (if defined) from our `state.list` 
      // or an empty array as our `list` GETTER method.
      const amenities = [ ...state.list?.data || [] ];
      
      // We could process again and even filter our amenities
      // Here we'll return a list of amenities with status `enabled` only
      return amenities.filter((a) => a.status === 'enabled'); 
    },
  },
  // Use MUTATIONS to set the data response to state.
  mutations: {
    set(state: any, payload: any) {
      // Our common API response is an object with a `data` and a `meta` property.
      // The `data` property has our list results, the meta has pagination information.
      // For now we will store the whole object to our `list` state.
      state.list = payload;
    },
  },
  // Use ACTIONS to call the service.
  actions: {
    async get(ctx: ActionContext<any, any>) {
      const result = await amenities.getAmenities();

      // Call our defined `set` MUTATION 
      ctx.commit('set', result);
    },
  },
};

# Step 3: Add the Module to the Store Index File

/src/store/index.ts

import amenities from './modules/amenities';

Vue.use(Vuex);

export default new Vuex.Store({
  state: ...,
  getters: ...,
  mutations: ...,
  actions: ...,
  modules: {
    // Add amenities module
    amenities,
  },
});

# Step 4: Use the Store in Components

To implement, let's hop over to src/views/main/Home.vue

<template>
<!-- We use our mapped and computed GETTER in the template -->
<pre>{{ JSON.stringify(list) }}</pre>
</template>

<script lang="ts">
import Vue from 'vue';
import { mapGetters } from 'vuex';

export default Vue.extend({
  name: 'Home',
  mounted() {
    // In the mounted hook, let's dispatch the store ACTION we defined
    // This will make an HTTP Request and set our `list` STATE 
    this.$store.dispatch('amenities/get');
  },
  computed: {
    // Use mapGetters to assign our amenities GETTER to a computed property in the component.
    // The computed property `this.list` will now exist, and will return our processed GETTER list.
    ...mapGetters('amenities', ['list']),
  }
});
</script>