0

https://stackblitz.com/edit/vue-script-setup-with-vuex-gfjaff?file=src/components/UserProfile.vue

I'm trying to be able to enter a name into the dispatch function and add it to an array. (Eventually I'd like to add a text input field, and enter it from there. Baby steps)

Then I'd like to be able to click a delete button near those names to delete it. I'm having a problem trying to implement "event.target.value". I think that's the problem anyways.

What am I doing wrong in this code? What part am I getting wrong?

store.js

import { createStore } from 'vuex'

export default createStore({
  state: () => ({
    list: ['bob', 'joe', 'harry'],
  }),
  getters: {
    listStatus: (state) => state.list,
  },
  actions: {
    addName({ commit }, { name }) {
      commit('ADD_NAME', name)
    },
    removeName({commit}, {name}) {
      commit('REMOVE-NAME', name)
    }
  },
  mutations: {
    ADD_NAME(state, name) {
      state.list.push(name)
    },
    REMOVE_NAME(state, event_target_name){
      state.list.filter(element=>element !== event_target_name)
    }
  },
})

userList.vue

<template>
  <div v-for="name in listStatus">
    <li>{{ name }}</li>
    <button @click="removeName(event.target.value)">Remove</button>
  </div>
  <button @click="addName">ADD NAME</button>
</template>

<script setup>
import { computed } from 'vue'
import { useStore } from 'vuex'

const store = useStore()
const listStatus = computed(() => store.getters.listStatus)
// const addName = (input_name) => store.dispatch('addName', { name: input_name }) --------- DOESN'T WORK
const addName = () => store.dispatch('addName', { name: 'tommy' })
const removeName = (event) => store.dispatch('remove-name', { name: event.target.value })
</script>
Eric Andre
  • 204
  • 2
  • 9
  • filter creates a new array. it doesnt act on the array from which it is called. So in REMOVE_NAME, 1) you're creating a new array and assigning it to nothing. 2) your original array (state.list) remains the same. – João Paulo Macedo Jan 17 '23 at 22:19
  • And there's a couple of other things that are wrong as well. I forked your example and fixed the stuff that's wrong (left the wrong stuff commented out) https://stackblitz.com/edit/vue-script-setup-with-vuex-fw5kds?file=src%2Fcomponents%2FUserProfile.vue,src%2Fstore.ts,src%2Fshims-vue.d.ts – João Paulo Macedo Jan 17 '23 at 22:24
  • [Here](https://stackblitz.com/edit/vue-script-setup-with-vuex-5fuhjp?file=src%2Fcomponents%2FUserProfile.vue,src%2Fstore.ts). Tip: take it slowly and use `console.log` at every step. – tao Jan 18 '23 at 01:14
  • And one more thing: swap `vuex` for [pinia](https://stackblitz.com/edit/vue-script-setup-with-vuex-jejjfr?file=src%2Fcomponents%2FUserProfile.vue). Much cleaner syntax. Check out [this answer](https://stackoverflow.com/a/71596533/1891677) for a longer list of reasons. – tao Jan 18 '23 at 01:39

2 Answers2

0

Use $event to access the event in an inline handler.

<button @click="removeName($event.target.value)">
Unmitigated
  • 76,500
  • 11
  • 62
  • 80
0

As mentioned in the documentation-

A method handler automatically receives the native DOM Event object that triggers it.

In your case, when the remove button triggers the removeName method, it will auto-receive the event, you don't need to pass it unless this is the only param you are passing.

Now, there are two problems in your code-

  1. You are passing event but you should use $event, a special variable. If you want to pass event, then use arrow function syntax. Read here.
  2. Even if removeName(event.target.value) works, then it means you are already passing the target value, then inside the method, you should access it like removeName(target_value) not removeName(event). By doing that, you are further trying to access value from the value itself.

So, do the following fixes in your code and it should work-

In template-

 <button @click="removeName">Remove</button>

In JS (same as you are using)-

const removeName = (event) => store.dispatch('remove-name', { name: event.target.value })
Neha Soni
  • 3,935
  • 2
  • 10
  • 32