davestewart / vuex-pathify

Vue / Vuex plugin providing a unified path syntax to Vuex stores
https://davestewart.github.io/vuex-pathify
MIT License
1.37k stars 57 forks source link

store.set not working on camelCase property with sub-property #51

Closed Balour closed 5 years ago

Balour commented 5 years ago

Hi,

I'm really loving this plugin, thank you for all of your work

I found a problem when wanting to use store.set if the property is in camel case

the line looks like store.set('ui/loggedUser@name')

if I change it from loggedUser to logged_user it works

Example codepen: https://codesandbox.io/s/nw3478yr0j

I can surely avoid using camelCase but I was wondering if it's a bug or something else and I did not see a warning in documentation

Thank you

davestewart commented 5 years ago

Hey, that's weird I'm checking it out now.

davestewart commented 5 years ago

Argh. That was a massive pain to debug!

Some tips:

However, I'm not sure if you've missed the point of Pathify?

You've got a lot of extra code, using actions, using Pathify inside of Pathify etc.

It's raised an interesting case I hadn't thought about, which is setting a sub-property from inside a store, but if you just want to set a sub-property on an object, you don't need to (shouldn't) make a method, to call an action, to call set() on the store, to access the commit on the same store, from outside the store.

Just use sync, and update the value in the component value +=1 or whatever.

Here's the (modified) demo of yours I used to find out what was going on:

But to the issue...

OK, it took me a while to get this one, but your problem is that you've imported your pathify config AFTER your module. This means that when the make.mutations() function runs, it has not yest imported your simple config and is creating SNAKE_CASE commits, thus the almost identically-named objects loggedUser and logged_user are both converted to logged_user, so only one of your actions worked.

You can check this by doing a simple console log on your mutations.

You have:

ui/SET_LOADING_CLIENT: [ƒ]
ui/SET_LOGGED_USER: [ƒ]

It should be:

ui/loadingClient: [ƒ]
ui/loggedUser: [ƒ]
ui/logged_user: [ƒ]

I hope that helps :)

davestewart commented 5 years ago

PS.

I did not see a warning in documentation

It's here:

Though there is a lot of docs. Sorry about that, I understand it could be easy to miss.

PPS.

Glad you are enjoying the plugin :)

Balour commented 5 years ago

Argh. That was a massive pain to debug!

Sorry about that haha

Some tips:

  • write cleaner demos. your code is all over the place!
  • write better markup; make it easy for the debugger to see what is going on!
  • only demo what is not working
  • remove code you're not using
  • don't try to be clever with alt and nested code etc

my real project ressembles nothing of the demo don't worry on that, I was trying to throw a quick codepen and since I don't know how to start one from scratch I started from the simple demo, I concede I should have cleaned up more

It's raised an interesting case I hadn't thought about, which is setting a sub-property from inside a store, but if you just want to set a sub-property on an object, you don't need to (shouldn't) make a method, to call an action, to call set() on the store, to access the commit on the same store, from outside the store.

Oh, for sure that was just for the demo, the real function is a server call and setting the return values

But to the issue...

OK, it took me a while to get this one, but your problem is that you've imported your pathify config AFTER your module. This means that when the make.mutations() function runs, it has not yest imported your simple config and is creating SNAKE_CASE commits, thus the almost identically-named objects loggedUser and logged_user are both converted to logged_user, so only one of your actions worked.

I hope that helps :)

That makes much sense! it makes sense but I'm not sure if I would have found so thank you

Glad you are enjoying the plugin :)

I used vuex-map-fields in my last form and oh man is pathify something else haha, thanks again

davestewart commented 5 years ago

By the way - if you just need to call servers, you might be interested in another project of mine, Axios Actions:

It's primarily designed to remove the expectation of coupling API calls with Vuex.

It's not right for all situations, but certainly something to consider if you find yourself creating stores only to call APIs and pass data back.

Balour commented 5 years ago

Hi again,

I'm still stuck on something, I still don't know how to properly commit a mutation on a sub property from within the same store

I have the following property in a module in my store

loggedUser: { id: '', username: '', no_employe: '', nom: '', email: '' }

I have an action setLoggedUser (located in the same module, triggered in main.js in beforeMount) which pulls the user from the server and then I want to set it in the store on the return.

I initially thought the way to go was to use store.set('ui/loggedUser@id', value) for each sub property as proposed in Issue #24

But as we've discussed it doesn't work (I checked config, it's set in simple for real). I did notice that the call to the server loops infinitely so that may be why it never sets. So definitely not the way to go.

So in order to commit a value to a sub-property in the store, do I need to do commit('loggedUser', new Payload(etc)) ?

If so the function by maimake in #24 might come in handy unless there's a better way

Thanks gain for your time

davestewart commented 5 years ago

I tell you what. Make a new issue with this, and I'll take a look at it there.

It is something I think needs looking at in the library in general.