Extracting data from a JSON string within a TXT document

I am looking to allow the user to select a file that will be read and parsed into JSON for storage in their localStorage. However, when reading from the file, each character is interpreted as a key, unlike when directly pasting the JSON string into the function where it is properly parsed.

Can anyone explain why the file method is not working as expected?

Below is the code responsible for reading the file (which results in every character becoming a key within LocalStorage).

<h1>Import/Export</h1>
        <button id="export">Export</button>
        <br><br>
        <input type="file" name="inputfile" id="inputfile">
        <br><br>
        <!-- <textarea id="input" placeholder="Paste the contents of the exported TXT file here"></textarea> -->
        <br>
        <br>
        <button id="import">Import</button>
        <pre id="output" style="display: none;"></pre>
        
        <script type="text/javascript">
            document.getElementById('inputfile').addEventListener('change', function() {
                var fr=new FileReader();
                fr.onload=function(){
                    document.getElementById('output').textContent=fr.result;
                    console.log(fr.result)
                    // Read the JSON
                    var data = JSON.parse(fr.result);
                    console.log(data)
                    Object.keys(data).forEach(function (k) {
                        localStorage.setItem(k, data[k]);
                    });
                }
                fr.readAsText(this.files[0])
            })
        </script>

And here is the code that works correctly either within a function or when executed in the console:

var data = JSON.parse("JSON STRING GOES HERE");
    console.log(data)
    Object.keys(data).forEach(function (k) {
        localStorage.setItem(k, data[k]);
    });

Answer №1

It is crucial to understand that localStorage key/value pairs can only be strings. (Refer to this StackOverflow answer for more insights).

There are two main issues to address:

Firstly, assuming your text file containing a JSON string resembles this (data extracted from JSON Placeholder):

"{\"posts\":[{\"userId\":1,\"id\":1,\"title\":\"sunt aut facere repellat provident occaecati excepturi optio reprehenderit\",\"body\":\"quia et suscipit\\nsuscipit recusandae consequuntur expedita et cum\\nreprehenderit molestiae ut ut quas totam\\nnostrum rerum est autem sunt rem eveniet architecto\"},{\"userId\":1,\"id\":2,\"title\":\"qui est esse\",\"body\":\"est rerum tempore vitae\\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\\nqui aperiam non debitis possimus qui neque nisi nulla\"}]}"

Upon running console.log(data), you will observe that your JSON string is partially parsed (the posts array objects remain as strings). To resolve this, consider double parsing the result to properly log the posts array as JavaScript rather than a string:

var data = JSON.parse(JSON.parse(fr.result));

Depending on the complexity of your JSON data structure, you may need to create or utilize a function that recursively parses the JSON string.

Secondly, as previously noted, localStorage exclusively accepts keys and values in string format. Even when implementing the suggested double parse method, remember that you are attempting to store a JavaScript object in localStorage, not a string.

Therefore, within your forEach loop while saving the data in localStorage, ensure to stringify it again:

Object.keys(data).forEach(function (k) {
  localStorage.setItem(JSON.stringify(k), JSON.stringify(data[k]));
});

Furthermore, when retrieving the data from localStorage, you must parse that specific JSON string into an object to access its values. Depending on the nature of the data being handled, you might want to explore utilizing IndexedDB or another conventional database solution instead.

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

Creating responsive tabs that transition into a drop-down menu for mobile devices is a useful feature for

I am looking to create a responsive tab design that drops down like the example shown below: Desktop/Large Screen View https://i.stack.imgur.com/hiCYz.png Mobile View https://i.stack.imgur.com/gRxLv.png I have written some code for this, but I am unsure ...

What is the most efficient way to organize information in the Firebase real-time database?

I'm having a tough time sorting data in the real-time database. I've been following the documentation and implementing the steps exactly, but so far, nothing seems to be working. I expected it to work similarly to filtering, which is functioning ...

JSONP is unable to utilize data fetched from an external API

I attempted to run an ajax request in order to retrieve a collection of items and display them through logging: https://i.stack.imgur.com/IK1qy.jpg However, when checking the console, the items appear as undefined: https://i.stack.imgur.com/3WOCa.jpg O ...

What is the method to create a resizable table column border rather than resizing the bottom corner border?

At the moment, we are able to resize the table border when we drag the corner. However, my goal is to enable resizing on the right side of the full border. https://i.sstatic.net/yFI24.png Below is the CSS code for resizing: th{ resize: horizontal; ove ...

Angular.js, Yeoman, and Grunt are essential tools for front-end

I've been working on developing an AngularJS application using Yeoman. Everything was going smoothly until I decided to implement some unit tests. Whenever I try to run my unit tests using grunt, I keep encountering the following error: Warning: Tas ...

The validation for the start and end dates in the datepicker is not functioning properly when

I have integrated a bootstrap date picker into my website. However, I am encountering an issue where the end date validation does not update when I change the start date after the initial selection. <script type="text/javascript" src="htt ...

You can see the JavaScript code directly in the browser

I'm completely puzzled as to why this is happening. How strange that the JavaScript code is visible on the browser, almost appearing like regular text on the web page. This mysterious occurrence seems to be exclusive to Firefox. Despite scouring vario ...

How can I continuously update a datetime tag every second within a Django Template?

I am currently working with Django 3, Bootstrap 4, and MySQL 5.7 on a Laragon server, all running on Windows 10. In one of my views, I have a variable dt_now = timezone.now() that I display in a Template using a simple <p>{{ dt_now }}</p> tag. ...

obtaining the data stored in the backing bean and showcasing it upon submitting the form

I currently have an a4j:commandbutton implemented on my jsf page. Here is the code snippet- <a4j:commandButton id="submitBtn" value="#{msgsMass.MM_04_02_BTN_CONTINUE}" reRender="addNewCardForm,saveAddNewCardForm" immediate="true" action="#{bBea ...

Different approach to loading Handlebars template instead of using fs.readFile with res.json in Express

In my efforts to create a straightforward live API endpoint (using res.json()) within an Express 4 application that merges Handlebars templates with data and sends back a string for client-side HTML replacement, I've encountered a challenge. The curr ...

Developing a personalized data binding feature with AngularJS and utilizing ng-repeat

Looking to design a unique controller that can display multiple similar objects connected to a dataset structured like this: [{name: card1, values: {opt1: 9, opt2: 10}},{name: card1, values: {opt1: 9, opt2: 10}}] The goal is to showcase the name and one ...

Utilize lodash to compare data between an array of strings and an array of JSONs

I have an array of email addresses as strings: var users = ["<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="17626472652657707a767e7b3974787a">[email protected]</a>","<a href="/cdn-cgi/l/email-protection" class ...

How to display a PDF file stored in the documents directory of an iOS device with Phonegap

I'm encountering an issue when it comes to displaying a PDF using HTML, PhoneGap, or JavaScript. The web application I'm working on is developed in Sencha Touch 2. Here's exactly what I need: I need to display a PDF file located in the d ...

Using array index to group colors in Javascript

Below is an array that I have: const colors = ['#54AAED', '#7BEA6B', '#f8b653', '#ff5584'] I am working on creating a function that can return a color based on the parameter group and index. For example: function ...

Choose an option from the dropdown menu when clicking on the radio button

My issue involves a drop-down menu along with two radio buttons, each with two values: jQuery('input[type=radio][name=radio_type]').change(function(e) { var value = jQuery(e.target.value); jQuery('select[name="optType"] option:selecte ...

Pressing the "Enter" key will submit the contents of

Hello, I have recently created a new chat box and everything seems to be working fine. However, I am facing an issue with submitting a message when I press enter (to go to the function Kucaj()). Can anyone provide assistance with this problem? I tried ad ...

Eliminate an item from an array of objects utilizing a specific key

Here is the JSON data provided: var data= { 'A' : { 'Total' : 123, 'Cricket' : 76, 'Football' : 12, 'Hockey' : 1, 'None' : 10 }, 'B&ap ...

What is the proper way to place a newly added element using absolute positioning?

Currently, I am in the process of developing a tooltip feature. This function involves adding a div with tooltip text inside it to the element that is clicked. However, I am facing a challenge in positioning this element above the clicked element every tim ...

Click on the link within the Checkbox label on MUI

I am working on creating a checkbox for the "Terms of Use," using FormControlLabel to nest a Checkbox. However, I also need to include a link that opens a Dialog component displaying the terms. The challenge is that clicking on the link checks the checkbox ...

Transmitting the Ctrl+A key combination to an element

My current testing framework is protractor, which I utilize for conducting end-to-end tests in Angular. When it comes to inputting text into an element, I typically use: element(by.model('myModel')).sendKeys('Test'); However, I am cu ...