0
votes

I've had some issues with Vuex. Here's the thing. I'm trying to do the 'Update' part of a CRUD, I'm able to show the information but on the console, it tells me these two errors:

[Vue warn]: Error in v-on handler: "TypeError: Cannot set property 'email' of undefined" TypeError: Cannot set property 'email' of undefined

(I'm only showing the email field to shorten the code, but the same errors happen with the rest of the fields).

Here's the following code:

Update.vue

<template>
  <v-container id="user-profile" fluid tag="section">
    <v-row justify="center">
      <v-col cols="12" md="8">
        <base-material-card icon="mdi-account-outline">
          <template v-slot:after-heading>
            <div class="font-weight-light card-title mt-2">
              Empleado
              <span class="body-1">— Registro de Empleado</span>
            </div>
          </template>
          <ValidationObserver ref="obs">
            <v-form>
              <v-container class="py-0">
                <v-row>
                  <v-col cols="12" md="4">
                    <VTextFieldWithValidation
                      label="Correo Electrónico"
                      color="secondary"
                      prepend-icon="mdi-at"
                      rules="required|email"
                      v-model="email"
                    />
                  </v-col>
                  <v-col cols="12" class="text-right">
                    <v-btn
                      color="success"
                      class="ml-0"
                      :to="{ name: 'UserList' }"
                    >
                      Atrás
                    </v-btn>
                    <v-btn
                      color="success"
                      class="mr-0"
                      @click.stop.prevent="submit"
                      @click="update()"
                    >
                      Modificar
                    </v-btn>
                  </v-col>
                </v-row>
              </v-container>
            </v-form>
          </ValidationObserver>
        </base-material-card>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
import { ValidationObserver } from 'vee-validate'
import VTextFieldWithValidation from '@/components/inputs/VTextFieldWithValidation'
import { mapActions } from 'vuex'

export default {
  data() {
    return {

    }
  },
  components: {
    ValidationObserver,
    VTextFieldWithValidation,
  },
  computed: {
    email: {
      get() {
        return this.$store.state.users.user.email
      },
      set(value) {
        const data = {
          key: 'email',
          value,
        }
        this.addUserData(data)
      },
    },
  },
  methods: {
    ...mapActions('users', ['fetchUser', 'addUserData']),
  },
  props: ['id'],
  async mounted() {
    await this.fetchUser(this.id)
  },
}
</script>

And my users.js store

import UserService from '@/services/UserService.js'
import * as types from '@/store/mutation-types'

const state = {
  users: [],
  user: {
    verified: false,
    email: '',
    empleado: {
      nombre: '',
      apellido: '',
      direccion: '',
      telefono: '',
    },
    tipo_usuario: '',
  },
}

const mutations = {
  SET_USER(state, user) {
    state.user = user
  },
  [types.FILL_USER](state, data) {
    state.user.verified = data.verified
    state.user.email = data.email
  },
  [types.ADD_USER_DATA](state, data) {
    switch (data.key) {
      case 'email':
        state.user.email = data.value
        break
      default:
        break
    }
  },
}

const actions = {
  fetchUser({ commit, getters, dispatch }, id) {
    var user = getters.getUserById(id)
    if (user) {
      commit('SET_USER', user)
    } else {
      UserService.getUser(id)
        .then((response) => {
          commit('SET_USER', response.data)
        })
        .catch((error) => {
          const notification = {
            type: 'error',
            message: 'There was a problem fetching user: ' + error.message,
          }
          dispatch('notification/add', notification, { root: true })
        })
    }
  },
  addUserData({ commit }, data) {
    commit(types.ADD_USER_DATA, data)
  },
}
const getters = {
  getUserById: (state) => (id) => {
    return state.users.find((user) => user.id === id)
  },
  users: (state) => {
    return state.users
  },
  user: (state) => state.user,
}

export default {
  namespaced: true,
  state,
  getters,
  actions,
  mutations,
}

Thanks in advance.

1
I only see two v-on handlers, @click.stop.prevent="submit" and @click="update()" (on the same element 😕) but you don't appear to have any methods by those namesPhil
I think your computed getter should be return this.$store.state.user.email. state.users is an array and is unlikely to have an .user propertyPhil
Yeah, I left those to v-on handlers by mistake, just one had to stay there and I didn't put the method for that yet. As for the computed getter, if I leave it as you suggested, it stops showing me the data. Also, for some reason this thing just fixed it by its own hahaha. The errors doesn't show up, it's kinda weird.Dany

1 Answers

0
votes

You access email from a "user" object in the template:

<v-col cols="12" md="4">
                    <VTextFieldWithValidation
                      label="Correo Electrónico"
                      color="secondary"
                      prepend-icon="mdi-at"
                      rules="required|email"
                      :value="user.email"
                    />

But your user isn't defined in the component. You have a computed "email" which you probably want to use to get the users email. So, remove the user and use your computed email.