Steve
Steve

Reputation: 4503

How to pass argument to $store.getters with onclick event?

How to pass argument to $store.getters with onclick event? I can see the default value but not the new value. This is my code

const store = new Vuex.Store({
  state: {
    notes: [
      { id: 1, text: 'Hello World 1, Vuex!', deleted: false}, 
      { id: 2, text: 'Hello World 2, Vuex!', deleted: true},
      { id: 3, text: 'Hello World 3, Vuex!', deleted: false}
    ]
  },    
  getters: {
    getNoteById: (state) => (id) => {
      return state.notes.find(note => note.id === id);
    }
  }
});    

new Vue({
  el: "#app",
  data() {
    return {
      result: '' 
    }
  },
  store,
  computed: {
    note() {
      return this.$store.getters.getNoteById(3);
    }
  },
  methods: {
    showText(id) {
      this.result = this.$store.getters.getNoteById(id);
    }
  }
});

and html

<div id='app'>
  <p>Default value: {{ note.text }}</p>  
    <button @click="showText('1')">1</button>  
    <button @click="showText('2')">2</button>  
    <button @click="showText('3')">3</button>    
  <p>New value: {{ result.text }}</p>
</div>

Upvotes: 2

Views: 128

Answers (1)

tao
tao

Reputation: 90078

Your getter is working perfectly. And it correctly returns undefined when searching for any item with an id of '1', '2' or '3'.

Because the store doesn't contain any such item.

All your store items have number ids, none of them has a string id. See it working (I changed the template to send numbers):

Vue.config.productionTip = false;
Vue.config.devtools = false;
const store = new Vuex.Store({
  state: {
    notes: [
      { id: 1, text: 'Hello World 1, Vuex!', deleted: false}, 
      { id: 2, text: 'Hello World 2, Vuex!', deleted: true},
      { id: 3, text: 'Hello World 3, Vuex!', deleted: false}
    ]
  },    
  getters: {
    getNoteById: (state) => (id) => {
      return state.notes.find(note => note.id === id);
    }
  }
});    

new Vue({
  el: "#app",
  data() {
    return {
      result: '' 
    }
  },
  store,
  computed: {
    note() {
      return this.$store.getters.getNoteById(3);
    }
  },
  methods: {
    showText(id) {
      this.result = this.$store.getters.getNoteById(id);
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.14/vue.js"></script>
<script src="https://unpkg.com/vuex"></script>

<div id='app'>
  <p>Default value: {{ note.text }}</p>  
    <button @click="showText(1)">1</button>  
    <button @click="showText(2)">2</button>  
    <button @click="showText(3)">3</button>    
  <p>New value: {{ result.text }}</p>
</div>


If, for any reason, you don't have control over the incoming type (you might have this problem when reading the value of an <input>, which is always a string, even when the type of the input is "number"), you might want to cast the value as number: +'5' => 5.
So, as an alternative to fixing the template, as above, you could do this in the method:

 showText(id) {
   this.result = this.$store.getters.getNoteById(+id);
 }

Upvotes: 2

Related Questions