electron-userland/electron-json-storage

JSON Changes Do Not Persist

Unknown025 opened this issue · 4 comments

Hello there!

I've been trying to figure out a very simple problem, and have come to a solution that doesn't sit well with me, so I wanted to reach out and double check.

I have some functionality that requires reading from a key, making changes to the object retrieved from that key, and writing those changes back to the original key. The problem is that the changes I make to that key don't get saved. I've verified that the changes don't just vanish into thin air, via use of Electron/Chrome's debugger, and through console statements. The original value of the retrieved key gets written back to the file. Here's a relevant example: Gist

The only meaningful solution I've found so far is to stringify the result of storage.get() and parse it back to JSON, which doesn't seem like a good solution. Writing entirely different objects, without calling storage.get(), works as expected. Anything I'm doing wrong? I'm using Electron 10 (though I updated from Electron 6, which had the same problem) combined with React.
I'm not an expert on JavaScript or Electron, so I'm hoping that I made a mistake somewhere. Everything is performed on the renderer, but I briefly tried using the backend process, to no avail.

Thanks in advance!

Hi @Unknown025 ,

That sounds pretty strange. We have many tests that cover similar scenarios (https://github.com/electron-userland/electron-json-storage/blob/master/tests/storage.spec.js) and most electron-json-storage users perform very similar workflows.

What operating system are you running this on? How does the object look like?

I'm wondering if this is related to the fact that you are running this code inside a React component. React component functions as synchronous, so they won't wait for the electron-json-storage-related async call chain to complete before returning. Even more, React components may re-render multiple times per second, so I wonder if you are getting into some sort of race condition involving reading & writing to that key.

In any case, I'm not a front-end developer, but I believe that having async code inside a React render function is an anti-pattern.

The only meaningful solution I've found so far is to stringify the result of storage.get() and parse it back to JSON, which doesn't seem like a good solution.

Sounds like multiple executions of that component render function might be re-using the same object pointer, therefore they modify each other in weird ways. This module does JSON.parse() and JSON.stringify() already before reading or writing to files, so I don't think the sharing of object pointers is happening within this module.

Can you confirm if this works outside of a react component? i.e. running once at initialisation of the web app?

I'm running on Windows 10, though intend to also test on macOS.

The object I'd like to save looks something like this: {"authenticationDatabase":{"testUuid2":{"name":"Some Name 2","display":"Something or other"}}}, essentially a dictionary of UUIDs with corresponding objects, normally containing a display name or JWT.

I tried running outside of React, during the initialization of the application, and have confirmed that electron-json-storage works perfectly fine, so looks like I'll have to figure out how to make it work with React.

Thanks for the help, I appreciate it. One last question though, is there any way to save a file with "pretty printing", instead of saving the object as a single line string?

I tried running outside of React, during the initialization of the application, and have confirmed that electron-json-storage works perfectly fine, so looks like I'll have to figure out how to make it work with React.

I'm glad you figured it out!

One last question though, is there any way to save a file with "pretty printing", instead of saving the object as a single line string?

We don't support that, but it would be interesting to support an option to pretty print before saving. This is the line that stringifies the object if you are up for sending a PR: https://github.com/electron-userland/electron-json-storage/blob/master/lib/storage.js#L316

#151 Alright, I've sent a PR.