-
Notifications
You must be signed in to change notification settings - Fork 30
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
Vuex state with a Class inside is working in background, but not in popup #17
Comments
Okay so I found a workaround, it's not really pretty but it works. I'm using a computed property that use a store's getter, and set prototypes on the fly. In my case, I do this: <script>
import { Game } from '../entities/Game';
import { Stream } from '../entities/Stream';
import { Channel } from '../entities/Channel';
export default {
computed: {
twitchChannels() {
return this.$store.getters.twitchChannels.map(channel => {
channel.__proto__ = Channel.prototype;
if (channel.stream) {
channel.stream.__proto__ = Stream.prototype;
if (channel.stream.game) {
channel.stream.game.__proto__ = Game.prototype;
}
}
return channel;
});
},
}
}
</script> EDIT: Something even better, make the getter setting prototypes on the fly (so we only do this only ONE time): import { Game } from '../entities/Game';
import { Stream } from '../entities/Stream';
import { Channel } from '../entities/Channel';
export new Vuex.Store({
state: {
twitchChannels: [new Channel(...)],
},
getters: {
twitchChannels(state) {
return state.twitchChannels.map(channel => {
channel.__proto__ = Channel.prototype;
if (channel.stream) {
channel.stream.__proto__ = Stream.prototype;
if (channel.stream.game) {
channel.stream.game.__proto__ = Game.prototype;
}
}
return channel;
});
}
}
}); |
Hey @Kocal, nice to see you here ^^ In first place thanks for the report and sorry for the delay, I'm passing on a very busy season and I can't answer before. It's the first time that I see a Vuex state storing a class instance, so I can't help so much before mount this enviroment and test it. The thing are amazing, didn't know that this are possible before, I think that the problem are on the serialization of data on the webextension message, this probably it's breaking the class object at some point. Are your project opensource to test it? If not don't worry, I can mount a simple enviroment to test this issue. Greetings |
Or maybe we can manually register prototypes: import { Channel } from './entities/Channel';
import { Game } from './entities/Game';
import { Stream } from './entities/Stream';
export new Vuex.Store({
plugins: [
VuexWebExtensions({
serializationPrototypes: {
Channel,
Game,
Stream,
}
})
],
}); Before serializing:
After unserializing:
I think it can works, but we should be careful about nested objects. |
Hi again @Kocal, after some days researching for this, can't offer any solution for now. I don't apply any serialization (the browser do it automatically), I try some things, only one work but it's so dangerous. The unic way that I found to restore class automatically with the plugin, it's jsonify the class methods as plain text, restore it with eval and then restore the values, it is the only thing that work for now but I can't implement it because security reasons. Eval are so dangerous and the review team of any browser gona reject the extensions that use it on any part. I don't have any more things for now, the best way that I see to restore the class, it's create new instance and then merge values with it but I can't do this on the plugin, you should import the class and create new instance manually. I think the best way it's add proto inside computed property, if you have any more things just say to me to try, |
Hi 👋
Ah yes, I forgot that you use
And what about #17 (comment)? |
This can be working I guess, it need a optional extra initialization and a serializer class to compare data structure of specified classes and assign his prototype, but can work I guess. I gona prepare and test this think and I come here with the feedback and the feature if it works. |
What level of nested structure depth should be cloned ? |
Hey! I finally have some time to use this Vuex plugin on a real project! :)
I think my problem is due to serialization/unserialization (JSON?) of my store state.
Given my store is:
When I use it in
background
,store.getters.firstChannel
is an instance ofChannel
class.But when I use it in my popup page inside a Vue component,
this.$store.getters.firstChannel
(ormapGetters(['firstChannel'])
) is a plain object, without prototype.I think it's a problem of serialization because some months ago, I had the same problem with
chrome.runtime.sendMessage()
. For each received data, I had to manually set__proto__
property:But in this case I don't know how to do this.
Maybe a store watcher inside my
popup/main.js
or a Vue watcher insidepopup/App.vue
?What do you think?
Thanks! :)
The text was updated successfully, but these errors were encountered: