Is there a simple method to sync with localStorage while preserving JavaScript data types?

My app is designed to interact with the localStorage by writing and reading data.

Essentially, I have an array of objects that undergo frequent changes throughout the code, and I want these modifications to be synchronized with the data stored in the localStorage.

I could potentially create a syncing function that updates the storage every time there's a change in the array. However, this method seems cumbersome and inefficient to me. For instance:

arrayOfObjects.push(newItem);
localStorage.setItem('objects', arrayOfObjects);

Followed by:

arrayOfObjects = localStorage.getItem('objects');
length = arrayOfObjects.length;

This approach would be suboptimal since it requires numerous read and write operations within the code, which is far from efficient.

Alternatively, I could encapsulate the synchronization process within a function so that all interactions with the array and localStorage go through it. Nonetheless, this solution might still lack functionality as dealing with arrayOfObjects as an array type for various operations like .push and .length will remain necessary.

Are there any suggestions on how I can streamline the synchronization of this array with the localStorage using minimal lines of code? Is there a way to directly manipulate an array type in localStorage without complex operations?

Answer №1

If you want to have an Array that automatically saves its data in LocalStorage whenever an operation is performed, you can create a custom Class that extends the native Array.

To restore this special Array from LocalStorage, you simply need to call its .restore() method.

Here's an example of how you can implement this:

class LocalArray extends Array {
  constructor(name, ...items) {
    super(...items)
    this._name = name
  }

  push(item) {
    Array.prototype.push.call(this, item)

    this._save()
  }

  pop() {
    const popped = Array.prototype.pop.call(this)

    this._save()

    return popped
  }

  // other operations like splice, reduce, etc..

  restore() {
    const data = window.localStorage.getItem(this._name)
    const items = data ? JSON.parse(data) : []

    items.forEach(item => {
      Array.prototype.push.call(this, item)
    })
  }

  _save() {
    window.localStorage.setItem(this._name, JSON.stringify(this))
  }
}

Usage example:

const users = new LocalArray('users')
users.push({ name: 'John Doe' })
users.push({ name: 'Mary Jane' })
users.pop()

Now, the LocalStorage would store the data as 'users': [{"name":"John Doe"}].

To restore the data:

const users = new LocalArray('users')
users.restore()

console.log(users) // logs [{ name: 'John Doe' }]

However, be cautious about performance implications. Each time you perform an operation like .push(), it triggers a _save() on the growing Array. One way to optimize this is by saving only changes (deltas) to LocalStorage instead of the entire object, but this adds complexity.

Handle with care.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Having issues with Bootstrap affix functionality malfunctioning

I recently put together documentation using the CSS and JavaScript from Bootstrap docs. Here is a snippet of the sidebar code in my documentation: <div class="col-md-3 docs"> <div class="bs-docs-sidebar"> <ul class="nav docs-sid ...

Empty Data Table Search After Refresh While Filter Remains Active

After testing the data tables library using their example code in a jsfiddle, it seems like there might be a bug. To recreate the issue, follow these steps: Open the JS Fiddle link https://jsfiddle.net/t4rphnuc/ Click "Run" In any footer search box, fil ...

Displaying text from an array in a div using JavaScript with a 2-second delay

I am relatively new to this, so please forgive me if something is not quite right. I have an array filled with different strings of text, and I want to display each string in an HTML div with a 2-second delay between each line. While I have managed to show ...

The indispensable field in my HTML form is failing to function

I have structured an HTML form with necessary fields and a Submit button triggering a function called add() on click. The HTML code snippet is as follows: Enter name: <div class="mb-3& ...

Guide to displaying PHP output in a format suitable for plotting

I'm currently working on plotting PHP output from a MySQL database using . The desired format for the output should look like this - var data = [ { x: ['giraffes', 'orangutans', 'monkeys'], y: [20, 14, 23], ...

Update a class based on a specified condition

Can I streamline the process of adding or removing a class from an element based on a variable's truthiness? Currently, my code seems overly complex: if (myConditionIsMet) { myEl.classList.add("myClass"); } else { myEl.classList.remove("myClass"); ...

Why is it that in IE9, submitting a basic form using jQuery doesn't seem to work?

Take a look at the code snippet below: <html> <head> <style type="text/css"> #myform {display:none;} </style> </head> <body> <button type="button" id="uploadbutton">Upload Images</button> <form name="myf ...

Ui Bootstrap (angularjs) sidebar is not functioning properly

I am encountering an issue with a sidenav that I am in the process of creating for one of my projects. The goal is to develop a side menu that shifts the content to the right when opened and returns it to the left when closed, essentially functioning as a ...

Utilizing PHP and jQuery Ajax in conjunction with infinite scroll functionality to enhance filtering capabilities

I have implemented infinite-ajax-scroll in my PHP Laravel project. This project displays a long list of divs and instead of using pagination, I opted to show all results on the same page by allowing users to scroll down. The filtering functionality works s ...

Switch the website title as soon as the user looks away from the tab

How can I capture the user's attention and bring them back to my website when they are on a different tab? I really like the effect used on sephora.pl where an alert pops up with the message 'What are you waiting for?' when you switch tabs. ...

Having trouble with a jQuery.validationEngine reference error?

Despite everything being correctly referenced, I am facing difficulties in getting it to function properly. It's strange because it worked once, but the validation message took 10 seconds to appear. After that, without making any changes, I tried agai ...

Encountering the "Local resource can't be loaded" error when attempting to link a MediaSource object as the content for an HTML5 video tag

I'm attempting to make this specific example function properly. Everything runs smoothly when I click the link, but I encounter an error when trying to download the HTML file onto my local machine and repeat the process. An error message pops up sayi ...

Dragging elements using the jQuery UI Draggable feature onto a designated droppable area

Struggling to implement a Draggable element on Droppable element using jQuery UI? I almost got it working, but the elements on the droppable area keep changing their positions when moved slightly. I want them to stay put, but return to their original place ...

How can I handle a 404 error if an object is not found in a JSON file?

Below is my code snippet where I check for the correct req.path and display specific text. However, I now need to show a 404 not found error message. I attempted placing it inside the for loop condition with break;, but it's not quite working as expe ...

combine several arrays next to each other based on a specified key

I have a collection of three sets, each containing three elements: Set1 = [[apple, 2, 4], [banana, 5, 5], [cherry, 4, 1]] Set2 = [[banana, 1, 7], [cherry, 3, 8], [date, 5, 4]] Set3 = [[apple, 5, 2], [banana, 0, 9], ...

What steps can I take to persistently subscribe to SignalR from an Angular service even in the event of connection failures?

Is there a way to safely attempt to connect to SignalR with intervals between attempts until the connection is established? Also, does anyone have advice on how to handle the different stages of connectivity to the web sockets effectively? We are utilizin ...

The best approach for setting a select value and managing state in React using TypeScript

Currently, I am in the process of familiarizing myself with TypeScript within my React projects. I have defined a type for the expected data structure (consisting of name and url). type PokedexType = { name: string; url: string; } The API respon ...

Missing information in input field using JQUERY

I've been attempting to extract a value from an input tag, but all I keep getting is an empty string. Upon inspecting the frame source, it appears as follows: <input type="hidden" name="" class="code_item" value="00-00000159" /> In order to re ...

Selecting the content within a table to easily edit it

I am working on a project where I have a table filled with data fetched from a database. My goal is to allow users to click on a cell in the table, make changes to its content, and then save those changes back to the database. Below is the code snippet I a ...

How to retrieve a JSON item without knowing the name of the parent key

When requesting JSON from Wikipedia's API, the URL is: http://en.wikipedia.org/w/api.php?action=query&prop=description&titles=WTO&prop=extracts&exsentences&explaintext&format=json This is how the response is structured: { ...