JSON.stringify does not transform arrays into strings

It seems like I may have approached this task incorrectly, perhaps due to mishandling recursion. I'm unsure of where the mistake lies. You can view the example here.

Below is the JavaScript code snippet -

function propertyTest(currentObject, key) {
    for (var property in currentObject) {
        if (typeof currentObject[property] === "object") {
            propertyTest(currentObject[property], property);
        } else {
            // Testing output only
            $('#method1').append((property == 'value' && key ? key : property) + ' -- ' + currentObject[property] + '<br />');
            propertyKey = (property == 'value' && key ? key : property);
            propertyValue = currentObject[property];
            var arrayJSON = [];
            arrayJSON.push(propertyKey);
            arrayJSON.push(propertyValue);
        }
    }
    var JSONString = JSON.stringify(arrayJSON);
    console.log(JSONString);
    return JSONString;
}

Here is the original JSON data structure -

// JSON data objects go here

The JSON data is passed to the function as follows -

propertyTest(oarsObject);

This snippet from the console shows where things seem to deviate -

// Console log details displayed here

There's inconsistency in the results and it appears that my recursive method might be flawed.

While JavaScript arrays typically require numerical keys, JSON.stringify() works differently on various data elements. The ultimate goal is to create small, individual JSON strings from this process. The desired output should consist of distinct key-value pairs similar to the example provided.

I seem to be struggling with extracting and formatting the pairs correctly rather than constructing the entire JSON string. Is creating an object instead of an array a potential solution? Or could there be other issues within my recursive approach?

Answer №1

When it comes to recursion and creating a single flattened array as the output, there are typically two approaches.

  • The first method involves passing the result array as a parameter, with each recursive call adding to it.
  • In the second approach, each function call returns an array which is then merged into the final result by the calling function.

Regardless of the method used, it's important to prioritize checking for Array type before handling Objects since Arrays are technically Objects too. This distinction is crucial because you may need to perform different operations based on their types.

Typically, processing of the final result (e.g., converting to JSON and logging) should be done outside the recursive function to maintain simplicity and efficiency.

Below is a demonstration of the first method, along with JSON conversion at the top level. I've endeavored to reuse your variable names as much as possible.

function propertyTest( currentObject, array, key ) {
   var result = array || [], o;

   if ( Array.isArray( currentObject ) ) {
      currentObject.forEach( function ( e ) { propertyTest( e, result ); } );

   } else if ( typeof ( currentObject ) === 'object' ) {

      if ( 'value' in currentObject && Object.keys( currentObject ).length === 1 ) {
         propertyTest( currentObject.value, result, key );

      } else {

         for ( var property in currentObject ) {
            propertyTest( currentObject[ property ], result, property );
         }

      }

   } else {
      result.push( o = {} );
      o[ key ] = currentObject;
   }

   return array === undefined ? JSON.stringify( result ) : result;
}

var oarsObject = [{
    "coordinateReferenceSystem": "26782,15851",
    "positionReferenceType": "geogWgs84",
    "geogWgs84": {
        "latitude": {
            "value": 0.50507158458214041
        },
        "longitude": {
            "value": -1.604064725846865
        },
        "height": {
            "value": 0.0
        }
    }
}, {
    "coordinateReferenceSystem": "26782,15851",
    "positionReferenceType": "geogWgs84",
    "geogWgs84": {
        "latitude": {
            "value": 0.50509265195620767
        },
        "longitude": {
            "value": -1.5961047836759397
        },
        "height": {
            "value": 0.0
        }
    }
}, {
    "coordinateReferenceSystem": "26782,15851",
    "positionReferenceType": "geogWgs84",
    "geogWgs84": {
        "latitude": {
            "value": 0.4963464715653228
        },
        "longitude": {
            "value": -1.5960947041991222
        },
        "height": {
            "value": 0.0
        }
    }
}, {
    "coordinateReferenceSystem": "26782,15851",
    "positionReferenceType": "geogWgs84",
    "geogWgs84": {
        "latitude": {
            "value": 0.49632551101280209
        },
        "longitude": {
            "value": -1.604015267530267
        },
        "height": {
            "value": 0.0
        }
    }
}];

alert( propertyTest( oarsObject ) );

Answer №2

Sheepy recommended scoping the result array outside of the recursive function.

It is advisable to use forEach for array values and for for objects containing objects. This approach simplifies the process by handling one object at a time without the need to manage the array manually.

Check out this Example on jsFiddle


var arrayJSON = [];

function testProperties(obj, key) {

    if (Array.isArray(obj)) {
        obj.forEach(testProperties);
    } else {
        for (var objKey in obj) {

            if (typeof obj[objKey] === 'object') {
                testProperties(obj[objKey], objKey);
            } else {
                var newKey = (objKey === 'value' && key) ? key : objKey;
                var newObj = {};
                newObj[newKey] = obj[objKey];
                arrayJSON.push(newObj);

                $('#method1').append( newKey + ' -- ' + obj[objKey] + '<br />');
            }
        }
    }
}

testProperties(oarsObject);
console.log(JSON.stringify(arrayJSON));

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

What is the process for transferring a Pulumi Output<T> to the container definition of a task in ECS?

When creating a generic ECS service that deals with dynamic data, it is important to note that the containerDefinition within a Task Definition must be provided as a single valid JSON document. The code snippet for this setup looks like: genericClientServi ...

Encountering an "AJAX not a function" error while using the d3/flask interface

Hey there! I'm new to the world of JavaScript and AJAX. Take a look at this d3 function I've been working on: var node = g.selectAll(".node") .data(root.descendants()) .enter().append("g") .attr("class", function(d) { return "node" + ...

Error encountered when trying to execute LaunchRequest for Alexa skill: The skill's response failed to properly execute

I am facing an issue with launching my Alexa skill called "Bigger Brain". Whenever I try to open it by saying "Open Bigger Brain" or "Launch Bigger Brain", Alexa responds with "There was a problem with the requested skill's response". I have tried tro ...

The empty string is not getting recognized as part of an array

Currently, I have a textarea field where pressing enter submits and creates a new item in the array. Pressing shift + enter creates a new line in the textarea input field. But when trying to submit by pressing shift and enter after creating a new line, it ...

filtering elements with selectable functionality in jQuery UI

I'm trying to exclude the <div> children from being selected within this list item and only select the entire <li>. The structure of the HTML is as follows: <ul id="selectable"> <li> <div id="1"></div> ...

Using a jQuery UI dialog for multiple checkbox selection. The post array cannot be saved for a multi-select until the dialog is opened

CSS <td class="cell"> <a class="opener" id="opener_'.$iterator.'" href="#" rel="#type_dialog_<?= $iterator; ?>">Click here</a> <div id="type_dialog_<?= $iterator; ?>" name="t ...

Incorporating Dynamic Events into HTML Generated on the Fly within a Vue.js Component

Currently, I am facing an issue where I am trying to dynamically generate HTML in a Vue.js component. While I have successfully rendered the HTML, I am struggling to connect the events for these dynamically generated elements. To illustrate this problem, I ...

What is the best way to prevent labels from floating to the top when in focus?

How can I prevent the label from floating on top when focusing on a date picker using Material UI? I have tried several methods but nothing seems to work. I attempted using InputLabelProps={{ shrink: false }} but it did not resolve the issue. Here is a li ...

animation of leaping to a specific element

I am currently working on a sidebar with links that have a hover effect to add a bullet. However, I want the bullet to smoothly follow the cursor's movement along the y-axis within the sidebar instead of jumping between the links. How can I achieve th ...

Learn the Method Used by Digg to Eliminate "&x=0&y=0" from their Search Results URL

Instead of using a regular submit button, I have implemented an image as the submit button for my search form: <input id="search" type="image" alt="Search" src="/images/searchButton.png" name="" /> However, I encountered an issue in Chrome and Fire ...

Retrieving information from an array in Laravel with keys that contain spaces

Currently, I am utilizing the Alpha Vantage API and making an external call. One issue that has arisen is that the response includes numerical values within the string. I'm exploring ways to parse this out using Laravel 5.2. Below are snippets of my c ...

Tips on avoiding page refresh when hitting the submit button:

I am working on a form that consists of one input field and one submit button. <form method='POST' action='' enctype='multipart/form-data' id="form_search"> <input type='hidden' name="action" id="form_1" va ...

Show an Array of Nested JSON API information on an HTML page using jQuery/JavaScript

Recently, I've delved into the world of jQuery, JavaScript, and AJAX while experimenting with an API that I designed. The backend result I received looks like this: [ { "id": 1, "choice_text": "They work on List View generally", ...

Guide on accessing CGI Script response using AJAX

Greetings, Here is the situation: I'm working on a login form. Once the submit button is clicked, it needs to trigger a CGI script called "someurl?userName=user&password=pwd". Depending on the response from the script, I should be able to navigat ...

What is the best way to showcase information from an external API in react js?

As I develop my new app, I am integrating API data from . This feature will enable users to search for their favorite cocktail drinks and display the drink name fetched from the API on the page. However, I am encountering an error that says "Uncaught TypeE ...

Looking to organize data based on duplicate values within an array using Javascript in the Vue framework

Can anyone provide assistance? Data = [{"name":A,"val":20}, {"name":B,"val":7}, {"name":C,"val":20}, {"name":D,"val":8}, {"name":E,"val":5}] SortedValue ...

Tips for concealing overlay when the cursor hovers

Can anyone help me with a code issue I'm having? I want to hide an overlay after mouse hover, but currently it remains active until I remove the mouse from the image. Here is the code: .upper {position: absolute; top: 50%; bottom: 0; left: 50%; tra ...

Obtain JSON data from an API and display it in a table using axios and Vue.js

I am working with a datatable and trying to populate it with data fetched from an API that returns JSON using the findAll() method from Sequelize. However, when I call the getUser method in console.log, it shows that the data is being retrieved. But when ...

Failed to retrieve Json data from the designated remote url

I have been trying to figure this out for hours. I'm struggling to retrieve the JSON data from a remote REST API. My goal is to fetch the JSON data and display the "html_url" field from it on my website. <html> <head> ...

Change the format of the array from the initial array to the new array structure

I have a multi dimensional array that I need to convert into the array2 structure. I've tried various methods, but all of them have resulted in bulky code and lots of iteration. Is there an easier way to accomplish this task? I am new to Angular and ...