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

Feature: Function to delete a subproperty store.delete #129

Closed aldencolerain closed 3 years ago

aldencolerain commented 3 years ago

I have a state with an object that maintains a collection, something like:

items: {
  'a': 'book',
  'b': 'hat'
}

It would be nice to be able to remove an item from this using vuex pathify. As I understand it, you can get a sub property with store.get('items@a') and set the property like store.set('items@a', 'shoe') but I haven't been able to find a way to remove an item. Hopefully I didn't just miss something in the documentation!

You can set the property to undefined, but that leaves the key intact when iterating. Also, you can get the entire collection, remove a key then set it but unfortunately you have to copy the object or use Vue.set to ensure reactivity.

So for example this doesn't work:

const items = store.get('items')
delete items.b
store.set('items', items)

This works:

const items = store.get('items')
Vue.delete(items, 'b')
store.set('items', items)

This works:

const items = store.get('items')
delete items.b
store.set('items', {...items})

I would be happy to make a pull request. It might also be worth considering if setting a key should go through and making the object deeply reactive again. It seems a bit unexpected.

davestewart commented 3 years ago

Hi.

Sorry for the delay in getting back to you.

Hmmm. Hadn't really thought about this use case before as I don't really use properties like that.

Generally collections in JS would be Arrays, and generally properties in Vuex state aren't deleted.

Pathify's "set" naming is really just a simplified convention / a bit of sugar over "commit"

I think if you want to do something like that, just set up your own mutation:

// items
const mutations = {
  remove (state, prop) {
    delete state[prop]
  }
}
this.$store.commit('items/remove', 'book')

I think unless this request got more support, it's not something I would consider implementing, sorry!

Hope that helps.

aldencolerain commented 3 years ago

@davestewart

No problem. Thank you for your work on your project and for the reply! I would be happy to implement it if its something you would consider merging. I think its very common to a collection using a key:value data in the state rather than in a array. This lets you key the collection and look up items efficiently. For example it is a recommended method for storing data in Redux: Normalizing State Shape.

The data I am storing is a normalized set of users keyed on their id. Currently I just retrieve the collection then edit it or I make a mutation as you suggested, but it seems like it would make the API a little more symmetric (even though its just a convenience api) to include the all three of the standard JS operations: get/set/delete.