Receiving Server Emissions in Vue/Vuex with Websockets

In my Vue component, I was using socket.io-client for WebSocket communication. Now that I've added Vuex to the project, I declared a Websocket like this:

Vue.use(new VueSocketIO({
  debug: true,
  connection: 'http://192.168.0.38:5000',
}));

new Vue({
  router,
  store,
  render: (h) => h(App),
}).$mount('#app');

1) Should I emit messages in the component itself or in the store?

I used to do something like this before introducing changes:

socket.on('connect', function () {
      console.error('connected to webSocket');
      socket.emit('my event', { data: 'I\'m connected!' });
    });

socket.on('my response', function(data){
      console.log('got response');
      console.log(data.data);
    });

After making the changes, I tried to do the same from a component like this:

    this.$socket.emit('my_event', { data: 'I\'m connected!' });
    console.error('send to websocket ');

    this.$options.sockets.my_event = (data) => {
      console.error('received answer ');
      console.error(data);
    };

The message reaches the flask server but the response receiving does not work. What am I doing wrong?

I also found some information about putting this in the store like:

SOCKET_MESSAGECHANNEL(state, message) {
      state.socketMessage = message
    }

I'm confused about what a channel is at this point. Is the my_response emitted from the flask server also considered a channel? Thanks for your help!

EDIT: I am now trying to interact with a websocket from my Vuex store. Here's what I've done so far:

Vue.use(new VueSocketIO({
  debug: true,
  connection: SocketIO('http://192.168.0.38:5000'),
  vuex: {
    store,
    actionPrefix: 'SOCKET_',
    mutationPrefix: 'SOCKET_',
  },
}));

In my store.js file:

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    count: 0,
    title: 'title from vuex store',
    isConnected: false,
  },
  mutations: {
    increment(state) {
      state.count += 1;
    },
    emitSth(state) {
      this.sockets.emit('my_event', { data: 'I\'m connected!' });
      console.log(state.count);
    },
    SOCKET_my_response(state) {
      state.isConnected = true;
      alert(state.isConnected);
    },
    SOCKET_connect(state) {
      state.isConnected = true;
      alert(state.isConnected);
    },
  },
});

In my component script:

export default {
  name: 'ControlCenter',
  data() {
    return {
      devices: [{ ip: 'yet unknown' }],
      thisDeviceIndex: 0,
      currentLayoutIndex: 0,
      layouts: [],
    };
  },
  computed: mapState([
    'title',
    'count',
  ]),
  components: {
    DNDAssign,
    FirstPage,
  },
  methods: {
    ...mapMutations([
      'increment',
      'emitSth',
    ]),
    incrementMutation() {
      this.increment();
    },
    emitEvent() {
      this.emitSth();
    },
  },
  created() {
    this.getAllLayouts();
    console.log(this.$socket);
  },
};

Button for emitting events:

<b-button
type="button"
variant="success"
v-on:click="emitEvent()"
>
emit event
</b-button>

The connected notification in the store works, but I encounter errors while emitting:

  • "TypeError: Cannot read property 'emit' of undefined"
  • "Cannot read property 'emit' of undefined"

I'm unsure about the naming convention for mutations. With the mutationPrefix set, should I just use "connect" instead of "SOCKET_connect"?

Answer №1

First and foremost, if you are utilizing Vue-Socket.io version 3.0.5 or newer, make sure to remove it and install version 3.0.5

npm uninstall vue-socket.io
npm install <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3e484b5b134d515d555b4a1057517e0d100e100b">[email protected]</a>

Then, lock the version in packege.json: "vue-socket.io": "3.0.5", as the latest update may cause issues with the library, more details can be found here

To receive events from the socket.io server, use:

this.sockets.subscribe("my response", (data) => {
    console.log(data);
});

If you prefer to add a listener at the component level, include the sockets object in the component export, for example:

export default {
    ...
    sockets: {
        "my response": function (data) {
            console.log(data);
        }
    }
    ...
}

If you are not integrating Vuex on VueSocketIO, there is no need to add additional functions in store mutations. To implement Vuex integration on VueSocketIO, include the vuex object when declaring the VueSocketIO class.

Below is a basic example for main.js

// Configure Vue to use Vuex
Vue.use(Vuex);

// Create store
const store = new Vuex.Store({
  state: {
      someData: null
  },
  getters: {},
  actions: {
      "SOCKET_my response"(context, data) {
          // Handle `my response`, manipulate the data by calling the "setData" mutation
        context.commit("setData", data);
      }
  }
  mutations: {
      ["setData"](state, data) {
          state.someData = data; // Update state with the received data
      }
  }
});

// Configure Vue to use VueSocketIO with Vuex integration
Vue.use(new VueSocketIO({
  debug: true,
  connection: 'http://192.168.0.38:5000',
  vuex: {
      store,
      actionPrefix: "SOCKET_"
    }
}));

new Vue({
  router,
  store
  render: h => h(App)
}).$mount("#app");

If you require an example of Vuex Integration, refer to my sample application that utilizes Vue and Vue-Socket.io with Vuex integration.te

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it possible to initiate validation on an HTML element without the presence of a form?

Is it possible to trigger validation on an HTML element without using a form? For example, I have set the required attribute on a field, but when I click the Save button, the field doesn't display the red outline indicating validation failure. I susp ...

Guide to switching classes with jquery

On my webpage, I have a star rating system that I want to toggle between "fa fa-star" and "fa fa-star checked" classes. I found some information on how to do this here: Javascript/Jquery to change class onclick? However, when I tried to implement it, it di ...

Encountering an unexpected token in the JSON file at the very start is causing an

An unexpected error has occurred, showing the following message:- Uncaught SyntaxError: Unexpected token u in JSON at position 0 The code causing the error is as follows:- import { useEffect, useState } from "react"; import { useNavigate, usePar ...

Guide on creating my inaugural HTML embeddable widget?

A client recently requested me to create a JavaScript (MooTools)/HTML/CSS/PHP based game as a deployable widget. This will be my first time developing a widget, so I am seeking advice and insights to help me navigate any potential challenges from experie ...

Ways to inspect a number within a span and adjust its color depending on the value?

Can someone help me figure out why this code is not reading the value correctly? Check it out here This is the HTML: <a class="InterestLink">Click me</a> <div id="InterestExpander"> <div id="InterestExpanderX"> ...

How can you toggle the visibility of a div based on detecting a specific class while scrolling?

My webpage features a sticky header that gains an extra .header-scrolled class when users scroll down. I am looking to switch the logo displayed in the header once it has been scrolled. Below is a simplified version of my HTML code: <header class=".he ...

Guiding Navigation with Vue-Router

In my authentication process using oauth2, the user is required to provide credentials. Upon validation, the authorization server issues an authorization with a callback URI auth/login/callback containing the parameter code. import Vue from 'vue' ...

The execution of ajax within a script being called by another ajax request is not functioning as expected in PHP

I am currently working on a project that involves three files, each serving a specific purpose as outlined below: //File1.php $('button.button1').click(function(e){ $.ajax({ type: "POST", url: "file2.php ...

Creating a JavaScript script to implement a CAPTCHA feature on Google Forms

I'm looking to implement a JavaScript solution that can prevent spam on Google Forms. The idea is as follows: Generate a random number a between 1 and 1000; Generate another random number b between 1 and 1000; Obtain input from the user, storing it a ...

Set the error state of a TextField in Material UI to true based on the user's input

Being a newcomer to React and Javascript, I have made some progress but now find myself stuck. I am struggling with how to change the error state of a Material UI TextField based on user input. Specifically, I want the error to be triggered if the user inp ...

The draggable=true attribute in EaselJS (MovieClip) canvas does not display a ghost image

I am currently working with a canvas element that contains animations powered by EaselJS. The canvas is wrapped in a parent div with draggable set to true. <div class="outer-parent" draggable="true"> <div class="inner-parent"> <canvas& ...

Leverage nan for the transmission and retrieval of Float32Array within an addon module

I am currently attempting to utilize nan in order to perform calculations on an array of floating point numbers within an add-on and then return the result as a Float32Array. However, while the arguments have IsNumber() and NumberValue() functions, there ...

Utilizing Lodash in TypeScript to merge various arrays into one cohesive array while executing computations on each individual element

I am working with a Record<string, number[][]> and attempting to perform calculations on these values. Here is an example input: const input1 = { key1: [ [2002, 10], [2003, 50], ], }; const input2 = { key ...

Experiencing difficulty in connecting with the service providers

What's the process for obtaining these providers? I recently followed the JavaScript Mastery tutorial step by step, however, I encountered an issue with the useEffect hook to fetch the providers (I even tried using alert to check, but it keeps showin ...

Can you share the outcomes of executing a Node.js program in real-time?

Is there a method to execute a program (such as tcpdump) and have nodejs capture the console output in real-time to display in an HTML format without saving it? I am interested in running a program that displays information in the console, with the capabi ...

Encountering SocketIO Connection Issue in NodeJS and NginX Configuration

Every time I attempt to access my nodejs application utilizing nginx, I encounter the ensuing error: 2015/04/20 22:34:08 [error] 29607#0: *1 connect() failed (111: Connection refused) while trying to connect to upstream, client: myipaddress, server: ...

Ensure that reactivity is applied only to nested properties

My data object consists of properties unrelated to vue/the UI and data that represents the state. I only want the state to be reactive, but I still need the complete object in the component. It's important that vue doesn't modify the other proper ...

Why is the image cut in half on mobile devices but displaying correctly on computer screens? Could it be an issue with

There seems to be an issue on mobile screens that does not occur on computer screens. When the user clicks on the image, it disappears, and when they click another button, it reappears. However, there is a problem with how the image appears - it is cut off ...

Ways to dynamically update the content of an HTML table without the need to reload the page

I'm currently working on an HTML table that retrieves data from a database and includes a button for deleting selected records. Here is what the table layout looks like: name phone links john 6562 link1 link2 link3 ___________ ...

Controller Function Utilizing Private Variable in AngularJS

After stumbling upon an Angularjs example online, I found myself perplexed. The code snippet in question is as follows: angular.module("testApp",[]).controller("testCtrl", function($scope){ var data = "Hello"; $scope.getData = function(){ ...