sindresorhus / electron-store

Simple data persistence for your Electron app or module - Save and load user preferences, app state, cache, etc
MIT License
4.55k stars 148 forks source link

Convenience methods #52

Open sindresorhus opened 5 years ago

sindresorhus commented 5 years ago

I propose adding some convenience methods to make common things easier.

What I do most of the time when using electron-store is to get a boolean and invert it. For example, store.set('isFoo', !store.get('isFoo')).

Would be nice to have:

.toggleBoolean(key) which accepts a key and toggles the boolean.

.appendToArray(key, newItem) which pushes a new item to the array. (#32)

.modify(key, mutateCallback) which would give you a callback to modify the value that you then return in the callback:

Before:

const array = store.get('array');
array.find(element => element.title === 'baz').src = 'something';
store.set('array', array);

After:

store.modify('array', array => {
    array.find(element => element.title === 'baz').src = 'something';
    return array;
});

These methods will require you to specify the key in the defaults option, so it would always work. If you try to use toggleBoolean() and the underlaying value is of a different type, it would throw an error.

Any other convenience methods we could add? I'm also interested in feedback on the method names.


*Note: While I opened the issue here, the methods we eventually go for should be added to conf.

austenc commented 5 years ago

New to using the library and I just tried to push stuff to an array, this would definitely be great to have! The toggleBoolean method would also be very useful!

ghost commented 5 years ago

I disagree about adding any convenience methods at all, as it breaks the SRP. toggleBoolean, incrementNumber, appendToArray, prependToArray, insertIntoArray or any other methods do not relate to storing data in electron, but they increase complexity and pollute the API. The only convenience method that makes sense is modify or patch; but, just like set, it should not return the modified value.

sindresorhus commented 5 years ago

@asmironov SRP?

ghost commented 5 years ago

@sindresorhus, well, the single responsibility principle. From the SOLID.

Electron storing arbitrary data in the json file is one thing, plain and simple. Modifying the data in that file, depending on its structure, is another. It's better not to mix them together.

y4ure commented 5 years ago

Will be great to have .modify(key, mutateCallback). I think it's the only one that is needed though, .toggleBoolean(key), .appendToArray(key, newItem) etc just looks a bit weird to me.

cliffordfajardo commented 5 years ago

I like the the modify method since it allows us to:

Another alternative:

Have the set method take an optional callback method which does the work of the proposed .mutate function. _This would require an addition to the Conf API?

//BEFORE
const array = store.get('array');
array.find(element => element.title === 'baz').src = 'something';
store.set('array', array);

//AFTER
store.set('some_arr', (array) => {
    array.find(element => element.title === 'baz').src = 'something';
    return array;
})

I agree with @asmironov _"convenience method that makes sense is modify (mutate)"

EDIT:

sindresorhus commented 5 years ago

This could also be useful:

Before

{
    label: 'Auto Hide Menu Bar',
    type: 'checkbox',
    checked: config.get('autoHideMenuBar'),
    click(item, focusedWindow) {
        config.set('autoHideMenuBar', item.checked);
        focusedWindow.setAutoHideMenuBar(item.checked);
        focusedWindow.setMenuBarVisibility(!item.checked);
    }
}

After

store.checkboxMenuItem(
    label: 'Auto Hide Menu Bar'
    click(item, focusedWindow) {
        focusedWindow.setAutoHideMenuBar(item.checked);
        focusedWindow.setMenuBarVisibility(!item.checked);
    }
)

I do this a lot in my apps and it would reduce the boilerplate.

sindresorhus commented 1 year ago

If anyone wants to work on this, see the initial attempt in https://github.com/sindresorhus/conf/pull/155 and the feedback given there.