Vue.js data not updating when receiving message from socket

Viewed 1415

I'm trying to design a vue.js app that updates data about the state of a game upon receiving a "new_state" message from a socket. The socket is implemented using django channels.

This is what the code looks like:

const ws_scheme = window.location.protocol == "https:" ? "wss" : "ws"

const gameSocket = new WebSocket(
    ws_scheme +
    '://'
    + window.location.host
    + '/ws/play/'
    + game_id
    + '/'
)
    let vue = new Vue({
        el: '#app',

        data: {
            current_turn: 0,
            last_turn: -1,
            current_card: 0,
            last_card: -1,
            number_of_stacked_cards: 0,
            last_amount_played: 0,
            won_by: -1,
            my_cards: [],
            other_players_data: {},
        },

        created() {
            gameSocket.onmessage = function(e) {
                data = JSON.parse(e.data)
                this.current_turn = data.state.current_turn
                this.last_turn = data.state.last_turn
               // ... update the other data
            };
        },
    });

When I receive the message, logging the data makes it apparent that I'm receiving correct information. However, if I go and type vue.current_turn after receiving the message, it's still 0 instead of the new value; same for all the other members of the data object. I tried with vue.current_turn = data.state.current_turn and it does work this way, but obviously it should work with this.

What's wrong with my code?

And generally speaking, what's the best way of accomplishing what I'm after, i.e. updating internal data variables upon receiving messages from a socket?

I have to do with without using the socket.io library, which isn't supported by channels.

1 Answers

The issue is that this is pointing to whatever calls gameSocket.onmessage, not the "normal Vue this".

To get around the issue you could do let self = this above gameSocket.onmessage and use self inside of it.

Related