Identifying the source object when using JSON.stringify

There is an object set up like this:

{
  item1: "value1",
  item2: "value2",
  item3: { 
      item4: "value4",
      item5: "value5" 
  }
}

The goal is to utilize JSON.stringify along with a replacer function that behaves differently for items 4 & 5, which are the inner properties of item3.
How can this be achieved?

A hypothetical approach could look something like the code below:

     return JSON.stringify(obj, (key, val) => {
         if (key is child of Item3) {
             return someOtherValue;
         } else {
             return val; 
         } 
}

The expected output in json format would be:

{ 
  "item1" : "value1", 
  "item2" : "value2", 
  "item3" : { 
      "item4" : "theSomeOtherValue", 
      "item5" : "theSomeOtherValue"
}

Edit:
Items 4 & 5 are dynamically generated and not known in advance. Only the title for item3 is known at runtime.

Answer №1

When tackling this issue, you have a couple of options available.

  1. Within the replacer function, the object being processed is represented by this. Therefore, when handling item4 and item5, this pertains to the item3 object. If there are distinguishing characteristics of that object, they can be identified based on this. It's important to utilize a conventional function instead of an arrow function so that JSON.stringify is able to define what this refers to during the replacer call.

  2. The replacer function receives the key and value being processed, so if the key of the object ("item3") is unique, special processing can be done when encountering it.

Here are a few examples for approach #1:

For example, if you possess a reference to the object, you can compare this to obj.item3:

const obj = {
    item1: "value1",
    item2: "value2",
    item3: { 
        item4: "value4",
        item5: "value5" 
    }
};
console.log(JSON.stringify(obj, function(key, value) {
//                              ^^^^^^^^^−−−−− Traditional function, not arrow function
    if (this === obj.item3) {
        console.log("do something different, it's " + key);
        return "theSomeOtherValue";
    }
    return value;
}));

If you do not possess a direct reference, any other identifying information about it can be used. For instance, with the given data, it's evident that it includes properties like item4 and item5:

console.log(JSON.stringify({
    item1: "value1",
    item2: "value2",
    item3: { 
        item4: "value4",
        item5: "value5" 
    }
}, function(key, value) {
// ^^^^^^^^^−−−−− Traditional function, not arrow function
    if (this.hasOwnProperty("item4") && this.hasOwnProperty("item5")) {
        console.log("do something different, it's " + key);
        return "theSomeOtherValue";
    }
    return value;
}));

These are just two illustrative cases; the key point is that this represents the object undergoing stringification.

As for approach #2, here's an instance:

console.log(JSON.stringify({
    item1: "value1",
    item2: "value2",
    item3: { 
        item4: "value4",
        item5: "value5" 
    }
}, (key, value) => { // It's okay if this one is an arrow function, we're not relying on
                     // `JSON.stringify` setting `this` for us
    if (key === "item3") {
        return {
            item4: "theSomeOtherValue",
            item5: "theSomeOtherValue"
        };
    }
    return value;
}));

If the entire path of the object under process is required, it may involve additional complexity but can be achieved as follows:

let paths = new Map();
console.log(JSON.stringify({
    item1: "value1",
    item2: "value2",
    item3: { 
        item4: "value4",
        item5: "value5" 
    },
    item6: {
        item3: {
            item4: "non-special item4",
            item5: "non-special item5"
        }
    }
}, function(key, value) {
// ^^^^^^^^^−−−−− Traditional function, not arrow function
    const path = paths.get(this);
    // Special processing for the properties of root.item3
    if (path === "root.item3") {
        return key === "item4" || key === "item5"
            ? "theSomeOtherValue"
            : value;
    }

    // Keep track of the path of the object
    for (const [k, v] of Object.entries(this)) {
        if (typeof v === "object") {
            if (path) {
                // The regex checks for property names that aren't valid(ish)
                // property names so we can use brackets notation
                paths.set(v, path + (/^\w+$/.test(k) ? "." + k : `[${JSON.stringify(k)}]`));
            } else {
                paths.set(v, "root");
            }
        }
    }
    return value;
}));

Answer №2

One way to handle the discovered desired object is to save it in a closure and adjust the output based on that object.

This method does not require the use of this.

function updater(parent) {
    let reference = {};
    return function (key, val) {
        if (key === parent) reference = val;
        return key in reference
            ? '#' + val
            : val; 
    };
}

var data = { item1: "value1", item2: "value2", item3: { item4: "value4", item5: "value5" } },
    jsonData = JSON.stringify(data, updater('item3'));

console.log(jsonData);

Answer №3

When using JSON.stringify, you can include a replacer function as the second argument. This function accepts both the key and value parameters, allowing you to customize the output based on specific conditions.

return JSON.stringify(obj, function(key, val) {
    if (this === obj.item3) {
        return "theSomeOtherValue";
    }
    return val;
});

Alternatively, you can achieve similar results by referencing the current key instead of using this:

return JSON.stringify(obj, function(key, val) {
    if (key === "item4" || key === "item5") {
        return "theSomeOtherValue";
    }
    return val;
});

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

Who is the father of Bootstrap Popover?

I'm currently facing an issue with getting a popover to be placed within a specific element. As of now, the popover is being inserted directly into the <body>, but I require it to be relative to other elements. I have been unable to locate a met ...

Utilizing a Spring Kafka listener to consume JSON data and automatically determine the corresponding domain object

I have a project where I need to process various types of JSON messages that will be published. Unfortunately, I cannot modify the publisher's code to include any headers. However, I am interested in utilizing @KafkaHandler to manage these different J ...

Identify whether the page is being accessed through the Samsung stock browser or as an independent web application

Hey there! I am on a mission to determine whether my webpage is being accessed through Samsung's default browser or as a standalone web app saved on the homescreen. Unfortunately, the javascript codes I have come across only seem to work for Safari an ...

The Restful API is receiving a request with an empty object

I am facing an issue with my MVC application where the API call is passing a null object. Despite debugging the code and confirming that the data fits the model before calling the API, the object appears to be null during the API call. Interestingly, all o ...

Using PHP with SQLSRV to generate and return JSON data

I recently made the switch to using a SQL Server database and I am still getting accustomed to the syntax. My current challenge is in trying to generate JSON output, but I am facing issues with the formatting. Below is a snippet of code from my PHP scrip ...

Utilizing Data Filters to Embed HTML in Vue.js?

I have been attempting to utilize the Filter feature in Vue.js to insert HTML tags within a String. The documentation indicates that this should be achievable, however, I am not having any success. The objective is for the data to be just a String that is ...

Troubles with showcasing user attributes in the view with ng-repeat and handle-bars in Angular.js

React.js, Express.js, MongoDB server.js: const express = require('express'); const mongoose = require('mongoose'); const bodyParser = require('body-parser'); const routes = require('./routes/index'); const users = ...

Show a virtual numeric keypad on the HTML input fields when they are set as type text specifically for mobile devices in a unique situation

When accessing the following web page from a mobile device, I currently have number input fields with comma separators added. However, in order to implement the comma separation function, I had to set the input type to text. This resulted in showing an alp ...

Merging nested JSON arrays with column groups in Snowflake

I am currently utilizing Snowflake for JSON parsing and have a query that produces a concatenated string for Resource and Action keys within the Statement array. Within GROUP and ROLE, there are multiple lists of Statements, and my goal is to create a sing ...

Ways to retrieve information when text is modified and a dropdown is selected within an input field

I have an input field with a text box and a dropdown. My goal is to trigger data based on text changes in one method, while using another method for the dropdown. Check out the code below. const allList = [ { id: "1", value: "Fruits" ...

Encountering issues with Jquery while retrieving data from a .json URL

While attempting to retrieve data using a small script that usually works with URLs producing JSON data, I encountered a syntax error when trying it with a URL ending in .json. //error Uncaught SyntaxError: Unexpected token : http://frontier.ffxiv.com/wo ...

What are some creative ways to incorporate images into SVG paths?

Check out my JSFiddle here. I'm attempting to position this image in the center of my arc. My initial thought was to use .attr("fill","url('somePicture')"), but so far, no luck with that approach. const width = 700; const height = 600; con ...

Tips for resolving error "Exception in main thread java.lang.NoClassDefFoundError: com/fasterxml/jackson/annotation/JsonView":

I am attempting to assess a json string by utilizing the jackson library's ObjectMapper. I have included the jackson-annotation, jackson-databind, and jackson-core dependencies with the matching version in the pom.xml file. However, the code is produc ...

The Heroku app is down because it can't find the module named 'hjson'

Recently, I integrated hjson into my Python application and hosted it on a Heroku server. However, upon pushing the updated code with hjson imports, my app crashed. Upon running heroku logs --tail, here is the stack trace: import config, requests, hjson 2 ...

Certain CSS styles for components are missing from the current build

After building my Vue/Nuxt app, I noticed that certain component styles are not being applied. In the DEVELOPMENT environment, the styles appear as expected. However, once deployed, they seem to disappear. All other component styles render properly. Dev ...

The CSS styles are failing to be applied to the submit button once it has been

When I have a form with a submit button that triggers a form submission on a PHP page, I want to have an onclick event on the submit button that changes its opacity using JavaScript. The issue I am facing is that after clicking the submit button, the opaci ...

A guide to seamlessly adding calendar events with JSON data using the powerful Ionic Native Calendar Plugin

Hello there, I am in the process of developing an Ionic app and incorporating the Ionic Native Calendar plugin. My goal is to utilize this plugin to dynamically adjust the calendar event parameters through JSON linked to a Firebase database, rather than h ...

Use .load() to set an image as background in the div

There is a block of code that is supposed to display images in a div with the class "img", but it isn't functioning correctly. Can you provide some guidance on how to fix this issue? <div class="other"><a href="/index1.html">Link1</a&g ...

Obtain information from a CSV document within Highchart Angular

Is there a way to access and retrieve data from a CSV file stored in the assets folder of my local system? The CSV file contains 5 or 6 columns of information. Important: This is an Angular project, therefore jQuery is not available. ...

Error in Oboe.js due to incorrect value

Originally posed by Sashkan in the Oboe.js Github issues: Receiving a streamed response from a remote API. Upon making an ajax call, the response looks like this: {"company_id":"3e1f975601f59090decc8f2d5ced72010162e481","airplane_type_id":"c10143316664f2 ...