Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error while using the library with Vuex in Quasar App #384

Closed
sandeeppsmys opened this issue Jun 20, 2019 · 27 comments
Closed

Error while using the library with Vuex in Quasar App #384

sandeeppsmys opened this issue Jun 20, 2019 · 27 comments
Labels
help wanted 🤝 Extra attention is needed question 🤔 Further information is requested

Comments

@sandeeppsmys
Copy link

sandeeppsmys commented Jun 20, 2019

Mutations are called when used with Store

My code looks like this..

[In App.vue]

import VueSocketio from 'vue-socket.io-extended'
import io from 'socket.io-client'
import store from './store'
Vue.use(VueSocketio, io(`http://${window.location.hostname}`), { store });

My mutation is like this in my store's mutations

SOCKET_message (state, data) {
    console.log(data)
  }

From the server, we are emitting ('message', data)
Please be noted that I am using Quasar and initializing it in App.vue. Works fine with components but not with Vuex store.

@sandeeppsmys sandeeppsmys changed the title Error while using the library with Vuex Error while using the library with Vuex in Quasar App Jun 20, 2019
@probil
Copy link
Owner

probil commented Jun 20, 2019

Hi @sandeeppsmys
your mutation should look like so

SOCKET_MESSAGE (state, data) {  // everything is in upper case
   console.log(data)
}

Can you try that?

@sandeeppsmys
Copy link
Author

sandeeppsmys commented Jun 21, 2019

Thanks Probil for the quick response.

Yeah I tried that one too.. But not getting mutated on the store.

Here is my store

export default function (/* { ssrContext } */) {
  const Store = new Vuex.Store({
    modules: {
      notificationManager
    },
    state: {
    },
    mutations: {
      SOCKET_MESSAGE (state, data) {
        console.log('SOCKET_MESSAGE')
        console.log(data)
      }
    },
    actions: {
      socket_message (context, data) {
        console.log('action SOCKET_MESSAGE')
        console.log(data)
      }
    },

    // enable strict mode (adds overhead!)
    // for dev mode only
    // strict: process.env.DEV
    strict: false
  })

  return Store
}

Please note that I am using a module 'notificationManager' and I tried placing the mutations there also but no luck.

@probil
Copy link
Owner

probil commented Jun 21, 2019

Hi @sandeeppsmys

Are you using server side rendering?
Are you sure path to socket io client is correct and connection with BE server is established?
Is there any errors in console?

@sandeeppsmys
Copy link
Author

I am using Quasar Development Server locally.
Yeah socket connection is established and also it works fine within the component using sockets{}
No errors on the console. It is just not calling the mutation.

@probil
Copy link
Owner

probil commented Jul 11, 2019

@sandeeppsmys Can you show me how do you trigger socket event on the server?

@sandeeppsmys
Copy link
Author

Service is in python.. Following line emits the socket event.
socketio.emit("delete_event", {"id": '12'})
I can receive it on the UI. But it is not just directly calling the mutation..

@probil
Copy link
Owner

probil commented Jul 26, 2019

@sandeeppsmys Then mutation should look like this:

SOCKET_DELETE_EVENT (state, data) {
   console.log(data); // prints -> {"id": '12'} 
}

@probil
Copy link
Owner

probil commented Jul 26, 2019

@sandeeppsmys If it doesn't help, can you please create a repo with a minimal reproduction of the bug? I'd like to resolve it

@probil probil added the question 🤔 Further information is requested label Jul 26, 2019
@badders
Copy link

badders commented Jul 29, 2019

Getting exactly the same issue, no socket mutation calls are working, but directly listending to the message on a component is fine

@probil
Copy link
Owner

probil commented Jul 29, 2019

Hi @badders 👋

Sound strange 🤔

Can you please create a repo with bug reproduction? I will be a HUGE step ahead.
I will be glad to fix!

@probil probil added the help wanted 🤝 Extra attention is needed label Jul 29, 2019
@KodeStar
Copy link

KodeStar commented Aug 2, 2019

@probil I think if you just install a base quasar build and select vuex during installation that will give you what you need https://quasar.dev/quasar-cli/cli-documentation/vuex-store

@probil
Copy link
Owner

probil commented Aug 2, 2019

Thanks @KodeStar
It's helpful. To be honest I don't have any experience with quasar so I will take a look during upcoming weekend

@KodeStar
Copy link

KodeStar commented Aug 2, 2019

I think it may not like my store, I'm doing the following in router/index.js:

import Vue from 'vue'
import VueRouter from 'vue-router'
import socketio from 'socket.io-client'
import VueSocketio from 'vue-socket.io-extended'
import store from '../store'

export const SocketInstance = socketio('http://localhost:3000')

Vue.use(VueRouter)
Vue.use(VueSocketio, SocketInstance, { store }) 

store/index.js looks like:

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

import app from './app'
import tags from './tags'
import websites from './websites'
import servers from './servers'
import terminals from './terminals'

Vue.use(Vuex)

export default function (/* { ssrContext } */) {
  const Store = new Vuex.Store({
    state: {
    },
    modules: {
      app, tags, websites, servers, terminals
    }
  })

  return Store
}

My store/terminals/mutations.js looks like:

export function SOCKET_CONSOLEKEY (state, payload) {
  console.log('hit the mutation')
}

I've also notice the following pop up in the console:

vue-socket.io-ext.esm.js?f87c:1 Uncaught TypeError: Cannot convert undefined or null to object
    at Function.keys (<anonymous>)
    at v (vue-socket.io-ext.esm.js?f87c:1)
    at d (vue-socket.io-ext.esm.js?f87c:1)
    at Socket.eval (vue-socket.io-ext.esm.js?f87c:1)
    at Socket.Emitter.emit (index.js?7297:133)
    at Socket.emit (socket.js?2851:138)
    at Socket.onconnect (socket.js?2851:335)
    at Socket.onpacket (socket.js?2851:232)
    at Manager.eval (index.js?40de:21)
    at Manager.Emitter.emit (index.js?7297:133)

If I remove the store parts and use sockets: {} directly on the component that works

@probil
Copy link
Owner

probil commented Aug 2, 2019

Wow 👍
It's definitely unexpected behaviour
I think there is a bug hiding somewhere 🐛

Thanks, @KodeStar for pointing out. You are cool 😎

@KodeStar
Copy link

KodeStar commented Aug 2, 2019

No, that error was my fault, I downloaded the src and imported it manually so I could find out where that error was coming from. I should have done:
import Store from '../store' rather than import store from '../store' and then Vue.use(VueSocketio, SocketInstance, { Store }) that clears up the error, now I can see the socket event firing inside the component with sockets: {} but still nothing from the mutation, I'll see if I can dig any further down now I can modify the code and see what the changes do

@KodeStar
Copy link

KodeStar commented Aug 2, 2019

Ok, so it seems in Main.js there is:
Observe(socket, options)
if I console.log(options) I get:
store
Then in Observe.js I added a console.log after export default (Socket, { store, ...otherOptions } = {}) => {
like so:

export default (Socket, { store, ...otherOptions } = {}) => {
  console.log(store)

and that returns undefined, which means the passToStore stuff never runs. I'm guessing the store being passed is different from what it's expecting or something?

@KodeStar
Copy link

KodeStar commented Aug 2, 2019

  function registerEventHandler () {
    augmentMethod(Socket, 'onevent', (packet) => {
      const [eventName, ...args] = packet.data
      console.log('onevent')
      console.log(eventName)
      console.log(...args)
      GlobalEmitter.emit(eventName, ...args)
      passToStore(eventName, args)
    })

I can see the events firing here, so it just never gets past the passToStore part as store is undefined

@KodeStar
Copy link

KodeStar commented Aug 2, 2019

Ok, I think it's because quasar uses modules rather than exposing its state/mutations/actions etc at the root level. If I create a new Vuex.store() just for this and pass that then the mutations get fired. Not ideal but will do for now I guess

@probil
Copy link
Owner

probil commented Aug 2, 2019

@KodeStar in this example #384 (comment)

  1. Your store.js returns a function instead of store.
    So you need to update it this way:
// router/index.js
///.. 
import store from '../store'

export const SocketInstance = socketio('http://localhost:3000')

Vue.use(VueRouter)
Vue.use(VueSocketio, SocketInstance, { store: store() }) // <-- calling store function here is important

But keep in mind that you should use the same instance of store in both vue-socket.io-extended and main app entry point.

So it may look like so:

import Store from '../store'

const SocketInstance = socketio('http://localhost:3000')
const store = Store(); // <-- here we create a real instance of the store

Vue.use(VueRouter)
Vue.use(VueSocketio, SocketInstance, { store }) // <-- here we use it

new Vue({
  el: '#app',
  store,  // <-- here we use it one more time but instance is the same
  render: h => h(App)
})
  1. vue-socket.io-extended expect store in a lowercase. E.g.
Vue.use(VueSocketio, SocketInstance, { store }) // right usage
Vue.use(VueSocketio, SocketInstance, { Store }) // wrong usage

@KodeStar
Copy link

KodeStar commented Aug 2, 2019

And it's working :) I think all it needed was the store: store() If it's using the same instance I'm not 100% sure as there isn't actually an instance of new Vue({ in the quasar app, I think that must be added when the app is built. I guess it must be though because this.$store.state.terminals returns the data being passed by the socket

@probil
Copy link
Owner

probil commented Aug 2, 2019

That's a good news!

@probil
Copy link
Owner

probil commented Aug 2, 2019

I've just checked quasar project a little bit. And there is not main app entry point. So my suggestion would be to wrap plugin registration and call it during store init.

E.g.:

// socket-plugin.js
import Vue from 'vue';
import io from 'socket.io-client';
import VueSocketIoExt from 'vue-socket.io-extended';

export const socket = io('http://localhost:3000');

export default function (store) {
  Vue.use(VueSocketIoExt, socket, { store });
}

Then

// store/index.js
import Vue from 'vue';
import Vuex from 'vuex';
import SocketPlugin from '../socket-plugin';

Vue.use(Vuex);

export default function (/* { ssrContext } */) {
  const Store = new Vuex.Store({
    mutations: {
      SOCKET_CONNECT() {
        console.log('CONNECTED');
      },
    },

    strict: process.env.DEV,
  });

  SocketPlugin(Store); // <--- this line connects plugin in right, quasar-compatible way!

  return Store;
}

I've just tried it on my local machine and it works just fine!

Can you check that @KodeStar and/or @sandeeppsmys ?

@KodeStar
Copy link

KodeStar commented Aug 2, 2019

I can confirm that works for me, though the previous store: store() worked for me also, I understand why this way works though so I'll stick with it. I think the other way worked as well because it was defined as a const so when it was called again it was still using the initial reference, either way it's all good.

@probil
Copy link
Owner

probil commented Aug 2, 2019

Thanks everyone.
Let me know if you have other questions

@probil probil closed this as completed Aug 2, 2019
@sandeeppsmys
Copy link
Author

Thanks probil.. its working for me too. Appreciate your efforts and enthusiasm in closing the issue.

@matiasjg
Copy link

I was facing the same issue but using NuxtJs and I found that the parameter store in the plugin file needs the {}:

export default (store) => { change to export default ({ store }) => {

plugins/vue-socket.js

import Vue from 'vue'
import VueSocketIOExt from 'vue-socket.io-extended'
import io from 'socket.io-client';

export default ({ store }) => {
  const socket = io('http://localhost:4000');

  Vue.use(VueSocketIOExt, socket, { store });
}

Hope it helps

@probil
Copy link
Owner

probil commented Mar 12, 2020

Thanks @matiasjg

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted 🤝 Extra attention is needed question 🤔 Further information is requested
Projects
None yet
Development

No branches or pull requests

5 participants