mohi666
mohi666

Reputation: 7072

Vuex state changes are not propagated to Vue component template

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.

Upvotes: 1

Views: 813

Answers (2)

mohi666
mohi666

Reputation: 7072

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.

Upvotes: 1

Jake Lam
Jake Lam

Reputation: 3472

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
  ]),
},

Upvotes: 2

Related Questions