1

I just started working on Vue and Vuex. I have created a component with its state data in Vuex. After an action, I can see my state changes applied in mutation, however, my Vue component is still not able to pick the new changes up.

Here's my store file:

const state = {
  roomInfo: {
    gameID: null,
    userID: null,
  },
  seats: null,
};

const getters = {
  seats: state => state.seats,
  roomInfo: state => state.roomInfo,
};

const actions = {
  async streamSeats({ commit }) {
    let connection = new WebSocket(`ws://localhost:8080/api/game/${state.roomInfo.gameID}/seats/${state.roomInfo.userID}`)

    connection.onmessage = function(event) {
      commit('setSeats', event.data);
    }

    connection.onopen = function() {
      console.log("Successfully connected to the echo websocket server...")
    }

    connection.onerror = function(event) {
      console.log("ERRR", event)
    }
  },
  async setRoomInfo({ commit }, roomInfo) {
    commit('setRoomInfo', roomInfo);
  },
};

const mutations = {
  setSeats: (state, seats) => {
    state.seats = seats
    // I can see changes here properly
    console.log(seats);
  },
  setRoomInfo: (state, roomInfo) => {
    state.roomInfo.gameID = roomInfo.gameID;
    state.roomInfo.userID = roomInfo.userID;
    if (roomInfo.seatNumber === 1) {
      state.seats.p1.id = roomInfo.userID;
    }
  },
};

export default {
  state,
  getters,
  actions,
  mutations,
};

And this is my component:

<template>
  {{ seats }}
</template>

<script>
  /* import API from '../api' */
  import { mapGetters, mapActions } from 'vuex';

  export default {
    name: "Seats",
    methods: {
      ...mapActions([
        'streamSeats',
        'setRoomInfo',
        ]),
    },
    computed: {
      ...mapGetters([
        'seats',
        'roomInfo',
        'setSeats',
      ]),
    },
    watch: {
      roomInfo: {
        handler(newValue) {
          if (newValue.userID && newValue.gameID) {
            this.streamSeats();
          }
        },
        deep: true,
      },
    },
    components: {},
    data: function() {
      return {
        alignment: 'center',
        justify: 'center',
      }
    },
    created() {
      let gameID = this.$route.params.id
      this.setRoomInfo({
        gameID: gameID,
        userID: this.$route.params.userID,
        seatNumber: 1,
      });
    },
  }
</script>

As you can see, I'd like to change the state data for seats inside state, after it connects to websocket server.

I have spent a long time trying to figure this out with no luck. I've tried to use mapstate, data, and a few other tricks without any luck. I tried all the suggested solutions in similar stackoverflow threads as well. I'd really appreciate if someone could give me some hints on how to pass this obstacle.

mohi666
  • 6,842
  • 9
  • 45
  • 51
  • At first glance it may be that you are not passing `state` into your action, like: `async streamSeats({ commit, state })` – csum May 26 '20 at 05:11
  • I have defined state as a global variable in store file. So it should be accessible everywhere. Note that I followed the project setup from this tutorial, which seemed nice and modular: https://www.youtube.com/watch?v=5lVQgZzLMHc&list=WL&index=244&t=2056s – mohi666 May 26 '20 at 05:18
  • ah, gotcha. I'm also seeing "seatsd" getter but that's probably just a typo. And are you getting any error messages? I would think {{ seats }} would need to be wrapped in a non-template element. – csum May 26 '20 at 05:46

2 Answers2

2

There are some mismatch when you define getters and call mapGetters

store

const getters = {
  seatsd: state => state.seats,   // there is a typo in seats, you declared seatsd
  roomInfo: state => state.roomInfo,
};

component

computed: {
  ...mapGetters([
    'seats',
    'roomInfo',
    'setSeats',  // this is not getters, this is mutations
  ]),
},
Jake Lam
  • 3,254
  • 3
  • 25
  • 44
  • Good catch. The typo was introduced while I was editing the question. I removed `setSeats` under components. However, the issue is still there. – mohi666 May 26 '20 at 07:36
1

Thank you for looking at it. I installed Vuejs chrome extension today. Apparently it changed the way errors were displayed in chrome dev console. I just noticed I had a few uncaught errors elsewhere, which didn't allow the code to go through these parts properly. After resolving those issues, I was able to see the data in my component.

mohi666
  • 6,842
  • 9
  • 45
  • 51