Get data from a JSON file using JavaScript

Dealing with a rather intricate and detailed JSON structure, I have a specific extraction task at hand.

The goal is to retrieve information (text) from the JSON only if the resource-id includes the text

"com.shazam.android:id/"
and certain properties (
["title", "subtitle", "datetime"]
) are present.

If the last element does not contain a datetime, then resorceIdFinal should not be included.

Below is a sample JSON that illustrates what I am aiming to achieve.

You can access the JSON I am working with through this link: https://pastebin.com/raw/hFLmP2T8

// JavaScript code snippets...

// Function to check presence of keys in an object
const check = (obj, keys) => !keys.some((el) => !obj.hasOwnProperty(el));

// Function to check if an object is empty
const isObjectEmpty = (objectName) => {
  return (
    objectName &&
    Object.keys(objectName).length === 0 &&
    objectName.constructor === Object
  );
};

// More functions related to processing the JSON data...

The desired JSON output:

[
   {
        "title": "Believe",
        "subtitle": "Chuther",
        "datetime": "12 giu, 16:42"
   },
   // Additional JSON objects...
]

Your assistance would be greatly appreciated!

Edit:

// Updated JavaScript code snippet...

// Function to check if an object is empty
const isObjectEmpty = (objectName) =>
(
  objectName &&
  Object.keys(objectName).length === 0 &&
  objectName.constructor === Object
);

// More updated functions for extracting information from JSON data...

Answer №1

This recursive function continues to call itself, but does not utilize the result:

const fetchChildren = (el, replaceText, props, resourceIdFinal) => {
  var childrenArray = [];

  el.forEach((element) => {
    let resourceId = findResourceId(element.attributes, replaceText, props, resourceIdFinal);
    if(!isObjectEmpty(resourceId)) childrenArray.push(resourceId);   
    //console.log(childrenArray);
    fetchChildren(element.children, replaceText, props, resourceIdFinal);
  });
  
  return childrenArray;
};

The return value of

fetchChildren(el.children, replaceText, props, resourceIdFinal)
is not being utilized. Make sure to add this result to the childrenArray if that was the intention:

const fetchChildren = (el, replaceText, props, resourceIdFinal) => {
  var childrenArray = [];

  el.forEach((element) => {
    let resourceId = findResourceId(element.attributes, replaceText, props, resourceIdFinal);
    if(!isObjectEmpty(resourceId)) childrenArray.push(resourceId);   
    //console.log(childrenArray);
    childrenArray.push(...fetchChildren(element.children, replaceText, props, resourceIdFinal));
  });
  
  return childrenArray;
};

It's important to note that there may be other issues in the code provided. This answer attempts to address the issue mentioned, but further debugging may be necessary. Consider using a debugger to identify any additional problems and ask separate questions if needed.

Answer №2

If your requirements remain consistent as discussed in the comments, you can extract the data by processing the json string line by line.

After reviewing the desired output and the source json, it appears that the text attributes within the json structure correspond to title, subtitle, and datetime. Whenever a text attribute is encountered sequentially, the algorithm stores it as the most recent one. Subsequently, when a specific indicator is detected, such as:

com.shazam.android:id/title
com.shazam.android:id/subtitle
com.shazam.android:id/datetime

... The previously saved text attribute is assigned to the corresponding property.
The detection of datetime denotes the completion of a record, which is then added to an array to facilitate the progressive creation of subsequent records.

The finer details are elucidated within the code itself and accompanying comments.

This demonstration exemplifies a functional approach. Simply copy and paste the json data into the provided text area before clicking the button. It's important for the json input to be correctly formatted; initially parsed and then serialized to ensure proper line separation. These steps may be bypassed once the input format is known to be compliant.

function extract( input_json ) {    
        
    // Assume the original json needs line-breaking:
    try {
        let _parsed = JSON.parse( input_json );
        input_json = JSON.stringify( _parsed , null, 1);
    }
    catch (e) {
        console.log("Error parsing json");
        return false;
    }
    
    
    // Convert into an array with each line as an index
    
    let json_lines = input_json.split("\n");
    
    
    // Proceed with a linear search to gather relevant data
    
    let output = []; // holds the final results
    
    let last_passed_text = ''; // retains the value of the last "text" attribute encountered
    
    
    let current_record = {}; // keeps track of the ongoing record construction
    
    
    for (let i = 0; i < json_lines.length; i++) {
        
        let textPos = json_lines[i].indexOf('"text"');
        
        if ( textPos > -1) {
        
            let _firstColon = json_lines[i].indexOf(":");
            
            if (_firstColon > textPos) {
        
            // Splitting at colon since `"text" :` signifies the sought definition
            
                let relevantPart = json_lines[i].substring( _firstColon + 1).trim(); 
            
            try {
                relevantPart = decodeURIComponent( relevantPart ); 
            }
            catch {}
            
                // Assuming the characters after colon act like `"abcdef",`, disregarding boolean values
                
                let token = relevantPart.substring(1,relevantPart.length-2); 
                
                last_passed_text = token.toString(); 
                
            }
        }
        
        if ( json_lines[i].indexOf("resource-id") > -1) {
            
            if ( json_lines[i].indexOf("com.shazam.android:id/title") > -1) {
                
                // Presence of title always marks the beginning of collection
                
                current_record = {};
                current_record.title = last_passed_text.toString(); 
                
                
            }
            else if ( json_lines[i].indexOf("com.shazam.android:id/subtitle") > -1) {
                current_record.subtitle = last_passed_text.toString(); 
               
            }
            else if ( json_lines[i].indexOf("com.shazam.android:id/datetime") > -1) {
                current_record.datetime = last_passed_text.toString(); 
                
                // Presence of datetime signifies end of collection
                
                output.push( JSON.parse(JSON.stringify( current_record )) );
                
            }
        }
    
    }
    
    return output;
}
Paste json here: (input)<br>
<textarea id="input-json" rows=15 cols=50></textarea>
<hr>
<button type="button" onclick="
    console.log( 
        extract( 
            document.getElementById('input-json').value
        ) 
    );">Extract To Console</button>

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

How can we avoid excessive re-rendering of a child component in React when making changes to the parent's state?

In my React application, I am facing a situation where a parent component controls a state variable and sends it to a child component. The child component utilizes this state in its useEffect hook and at times modifies the parent's state. As a result, ...

Navigating through different components in Angular without using templates

Searching for a straightforward solution using Angular to manage routes. I have a webpage generated by the server featuring a basic Google map and some logic spread across three separate controllers. Now, I aim to integrate routing into this setup. Nothi ...

Utilize React to extract a JSON object nested within an array and then implement a dropdown sorting feature for the JSON

Can anyone help me figure out how to extract the eventId and title from the "currentSchedule" array nested within the main "response" array? I have successfully looped through all the data in the "response" array dynamically, ...

JsonResult from MVC contains information, yet the browser is devoid of any data

In my controller method GetLayer2(), it bears a striking resemblance to GetLayer0() and GetLayer1() [HttpGet] public async Task<JsonResult> GetLayer2(string datePassedIn, string eventType, string driverId) { string orgCode = "HVO"; //User.Identi ...

Unlocking the true potential of JSON data encoding in PHP

While attempting to retrieve an object from my controller, the console.log(response) function displays the correct value: [ { "itemValue":100, "itemUnit":"2" } ] However, when trying to access the object using ...

Maintaining the dropdown in the open position after choosing a dropdown item

The dropdown menu in use is from a bootstrap framework. See the code snippet below: <li id="changethis" class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown>LINK</a> <ul class="dropdown-menu"> <li id ...

Is there a way to configure eslint to recognize and allow the nullish-coalescing assignment syntax?

The "nullish-coalescing assignment" operator, ??=, has been around for some time now in JavaScript. However, it appears that even newer versions of eslint, like 8.38.0, do not seem to recognize it and throw a syntax error regarding the assignment ...

Is there a way to make JavaScript function properly with PHP-generated content?

I have a PHP file that loads a variety of forms depending on an identifier passed through a GET request. Everything is functioning properly, except for my JavaScript/jQuery code. Is there a way I can refresh the JavaScript to make it work with the form? ...

The model in the Schema has not been registered, unlike other models from the same source that have been successfully registered

When populating a node express route with information from Schemas, I encountered an error that puzzles me. Even though I am referencing three different fields in the same Schema, I am only facing this error for one of those fields. The specific error mes ...

How to troubleshoot Python errors (+mod_wsgi) using the Chrome Network panel

As a newcomer to Python, I am facing an issue with viewing error messages. The problem arises when a javascript function is making a call as follows: $.getJSON('test.py', {data: 'somedata'}, function(return){alert(return.echo)}) In th ...

Mocha Chai: Dive into an array of elements, discovering only fragments of the desired object

Currently, I am utilizing the assert syntax of chai. I have a dilemma regarding checking an array of objects for a specific object. For example: assert.deepInclude( [ { name: 'foo', id: 1 }, { name: 'bar', id: 2 } ], { n ...

How to send a JSONArray with just a single string using retrofit

As I attempt to send a server request, the expected body for this request is ["1"] However, sending a string as "[\"1\"]" results in an error Upon inspecting the body, it is evident that I need to send a JSONArray. I attempted to achieve this u ...

The concept of setTimeout and how it affects binding in JavaScript

I have limited experience with jquery, mainly using it for toggling classes. However, I will do my best to explain my issue clearly. I have three div elements and when one is clicked, the other two should rotate 90 degrees and then collapse to a height of ...

What is the best way to incorporate a logo container and a horizontal divider into my top navigation bar using Bootstrap?

I'm currently working on designing a top navigation bar that features a logo with color #1 as the background on the left side. The logo is then separated by a grey horizontal divider, followed by color #2 representing the application name beside the d ...

Unable to retrieve the previous API response and add it to the URL for the POST request API

Trying to send a POST API request and receiving the following response: "d": { "__metadata": { "uri": "http://ev-qa02.zs.local/IncentiveManager/0002i1/wcf/v5.svc/InDataRequestCreators('9f31c6da-ec56-4360-8589-d21b6320f99b')", "ty ...

Trigger an alert message upon loading the HTML page with search text

I need to search for specific text on a webpage and receive an alert if the text is found. <script type='text/javascript'> window.onload = function() { if ((document.documentElement.textContent || document.documentElement.innerText ...

Combining the inline JavaScript linting tool ESLint with the popular Airbnb configuration and Facebook

In my current project, I am utilizing ESLint and looking to incorporate Facebook flow. However, I am encountering warnings from ESLint regarding flow type annotations. Within the project root directory, I have both .flowconfig and .eslintrc files present. ...

Tips for displaying the HTML content within the autocomplete box

My situation involves a text input and an HTML form where users can submit their name to retrieve information. I am using AJAX to display the usernames dynamically. <div class="hidesearch" id="search" style="width:"400px;"> <inp ...

Options menu in an Android Studio application

Having just begun my journey with Android Studio, I am facing difficulties in creating a menubar. Despite my efforts to find solutions, none of them seem to work out. I attempted the following code snippet, but I feel stuck at this point: public class Ma ...

Showing the advancement of a String[] in Android app

After parsing some XML, I have obtained a String[][]. However, I am encountering difficulties when trying to pass this array to the protected void onProgressUpdate(String... values) { method. I am struggling to extract the values from the array. Here is t ...