Perez Macdonald
Perez Macdonald

Reputation: 45

Vuejs error: Property or method "products" is not defined on the instance but referenced during render

Im new too nuxtjs and vuex, unfortunately i got some errors trying too fetch my data from vuex;

[Vue warn]: Property or method "products" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.

./pages/index.vue

<template>
  
  <div>
    <TheCarousel />


    <SellingItems 
     v-for="prod in products"
     :key="prod.id"
     :id="prod.id"
     :image="prod.image"
     :name="prod.name"
     :price="prod.price"
    />
  </div>


</template>

<script>
import TheCarousel from '../components/TheCarousel'
import SellingItems from '../components/sellingItems'
import { mapGetters } from 'vuex'

export default {
  components: {
    TheCarousel,
    SellingItems
  },

  computed: {
    //  products(){
    //    return this.$store.getters['prods/products']
    //  }
     ...mapGetters(['prods/products'])
  }
}
</script>

./components/sellingItems.vue

<template>
  <v-container class="my-5">
    <h2>Top Selling Items</h2>
    <v-divider class="my-4"></v-divider>

    <v-row>
        <v-col
        sm="6"
        md="4"
        v-for="product in products"
        :key="product.name">
          <v-card outlined>
            <v-img :src="product.image" height="200px" />
            <v-card-title> {{ product.name}} </v-card-title>
            <v-card-subtitle> ${{ product.price }}</v-card-subtitle>

            <v-card-actions>
                          <v-btn color="success" outlined to="#">
                              <v-icon small left> add </v-icon>
                              Add to Cart
                          </v-btn>
            </v-card-actions>
          </v-card>
        </v-col>
    </v-row>
  </v-container>
  
</template>

<script>
export default {
   props: ['id', 'image', 'name', 'price'],
}
</script>

<style>

</style>

store/modules/product.js

export default {
    namsespaced: true,
    state(){
        return{
            products: [
                {
                    id: '1',
                    name: 'Playstation 4', 
                    price: 200, 
                    image: 'img/ps4.jpg'
                },
                {
                    id: '2', 
                    name: 'Playstation 5', 
                    price: 700, 
                    image: 'img/ps5.jpg'
                },
                {
                    id: '3', 
                    name: 'Nintendo wii', 
                    price: 100, 
                    image: 'img/wii.jpg'
                }
            ]
        }
    },

    getters: {
        products(state){
            return state.products;
        }
    }
}

Upvotes: 0

Views: 2682

Answers (1)

hvaughan3
hvaughan3

Reputation: 11105

  1. You are passing in each item's properties into SellingItem but then in selling items, you are looping through products which does not exist in that component. Did you mean to use the passed in properties instead?

To use those passed in properties, reference them the same as if they were defined in data or computed:

    <v-row>
        <v-col sm="6" md="4">
          <v-card outlined>
            <v-img :src="image" height="200px" />
            <v-card-title> {{name}} </v-card-title>
            <v-card-subtitle> ${{price}}</v-card-subtitle>

            <v-card-actions>
                          <v-btn color="success" outlined to="#">
                              <v-icon small left> add </v-icon>
                              Add to Cart
                          </v-btn>
            </v-card-actions>
          </v-card>
        </v-col>
    </v-row>
  1. Your mapGetters is not defined correctly from within index.vue. Try this:

...mapGetters('products', ['products'])

And you would reference it like this.products.

The namespace would only be needed, from my understanding, if this Vuex store were nested in a parent store or if the getter was being called from within another Vuex store. For your example, calling with namespace from within a separate Vuex store's action would look like: const value = context.rootGetters['products/products']

Having said all of that, if your getter just returns the state item itself without any other logic, you might as well call the state item directly instead of going through a getter.

Upvotes: 2

Related Questions