javascriptnuxt.jsvuex-modules

Cannot read properties of undefined (reading 'getters')


Can anyone help with the below, I am getting the following error Cannot read properties of undefined (reading 'getters')

I am working on a project where my stores should return an array to my index.vue

Is there also any way I can get around this without having to use the Vuex store?

My store directory contains the below files

index.js

export const state = () => ({})

parkingPlaces.js

import {getters} from '../plugins/base'

const state = () => ({
  all: []
});

export default {
  state,
  mutations: {
    SET_PARKINGPLACES(state, parkingPlaces) {
      state.all = parkingPlaces
    }
  },
  actions: {
    async ENSURE({commit}) {

        commit('SET_PARKINGPLACES', [
          {
          "id": 1,
          "name": "Chandler Larson",
          "post": "37757",
          "coordinates": {
            "lng": -1.824377,
            "lat": 52.488583
          },
          "total_spots": 0,
          "free_spots": 0
        },
        ]
        )
      }
    },
  getters: {
    ...getters
  }
}

index.vue

<template>
  <div class="min-h-screen relative max-6/6" >
    <GMap class="absolute inset-0 h-100% bg-blue-400"
      ref="gMap"
      language="en"
      :cluster="{options: {styles: clusterStyle}}"
      :center="{lat:parkingPlaces[0].coordinates.lat, lng: parkingPlaces[0].coordinates.lng}"
      :options="{fullscreenControl: false, styles: mapStyle}"
      :zoom="5"
    >
      <GMapMarker
        v-for="location in parkingPlaces"
        :key="location.id"
        :position="{lat: location.coordinates.lat, lng: location.coordinates.lng}"
        :options="{icon: location.free_spots > 0 ? pins.spacefree : pins.spacenotfree}"
        @click="currentLocation = location"
      >
        <GMapInfoWindow :options="{maxWidth: 200}">
          <code>
            lat: {{ location.coordinates.lat }},
            lng: {{ location.coordinates.lng }}
          </code>
        </GMapInfoWindow>
      </GMapMarker>
      <GMapCircle :options="circleOptions"/>
    </GMap>
  </div>
</template>

<script>

import {mapGetters, mapActions} from 'vuex';




export default {




 // async mounted() {
 //   //  // console.log('http://localhost:8000/api/parkingPlace')
 //   // console.log(process.env.API_URL)
 //   // const response = await this.$axios.$get('PARKING_PLACE')
 //   //
 //   //  console.log('response', response)
 //
 //   // console.log(location)
 //  },

  data() {
    return {
      currentLocation: {},
      circleOptions: {},
      // parkingPlaces: [
      //array of parkingPlaces
      // ],
      pins: {
        spacefree: "/parkingicongreen3.png",
        spacenotfree: "/parkingiconred3.png",
      },
      mapStyle: [],
      clusterStyle: [
        {
          url: "https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m1.png",
          width: 56,
          height: 56,
          textColor: "#fff"
        }
      ]
    }
  },

  computed: {
    ...mapGetters({
      'parkingPlaces': "parkingPlaces/all"
    })
  },

  async fetch() {
    await this.ensureParking()
  },
  methods: {
    ...mapActions({
      ensureParking: 'parkingPlaces/ENSURE'
    })
  }
 }
</script>

base.js

import getters from "./getters";

export {getters};

getters.js

export default {
  all: state => state.all
};

Image of my file directory below enter image description here

image of error enter image description here


Solution

  • why you need state management :

    Vuex is a state management pattern + library for Vue.js applications. It serves as a centralized store for all the components in an application, with rules ensuring that the state can only be mutated in a predictable fashion.

    today you can try nuxt3 then you have access to Nuxt3 state management or try Pinia not Vuex these are better options for Vue3.

    if you want to use Vue2, Nuxt2 and Vuex as state management so:

    first why your getters file is in plugins?

    use this structure:

    |__store

    ⠀⠀|__ index.js

    ⠀⠀|__ getters.js

    your getter file content should be like this :

    export default {
     //your getters
    };
    

    then you can import these getters in your index.js file like this:

    import getters from "./getters";
    const store = createStore({
      state () {
        return {
          something: 0
        }
      },
      getters
    })
    

    and then you use mapGetters:

    ...mapGetters({
      parkingPlaces: 'all'
    })
    

    if you have another store you should use modules :

    const moduleA = {
      state: () => ({ ... }),
      mutations: { ... },
      actions: { ... },
      getters: { ... }
    }
    
    const moduleB = {
      state: () => ({ ... }),
      mutations: { ... },
      actions: { ... }
    }
    
    const store = createStore({
      modules: {
        a: moduleA,
        b: moduleB
      }
    })
    

    you can separate files and the structure will be:

    |__ store

    ⠀⠀|__ index.js # where we assemble modules and export the store

    ⠀⠀|__ actions.js # root actions

    ⠀⠀|__mutations.js # root mutations

    ⠀⠀|__ modules

    ⠀⠀⠀⠀|__ moduleA.js # moduleA module

    ⠀⠀⠀⠀|__ moduleB.js # moduleB module