JavaScript - Combining nested arrays of JSON data into a single object

I'm looking to convert a nested JSON structure into a single object with dynamic keys. I attempted the code below, which only works for one level. I need help writing a recursive function to handle n levels of nesting. Any advice would be appreciated.

   data.map((e) => {
   for (let key in e) {
     if (typeof e[key] === "object") {
       for (let onLevel in e[key]) {
         e[key + "." + onLevel] = e[key][onLevel];
       }
     }
   }
 });

Example

Input JSON

[{
  "Id": "0hb3L00000000jkQAA",
  "Name": "P-2797",
  "ContactEncounterId": "0ha3L000000001qQAA",
  "StartTime": "2020-06-27T11:00:00.000Z",
  "EncounterDuration": 25,
  "ContactEncounter": {
    "Name": "Grocery Shopping 17",
    "LocationId": "1313L0000004ENlQAM",
    "Id": "0ha3L000000001qQAA",
    "Location": {
      "Name": "Waitrose",
      "LocationType": "Site",
      "Id": "1313L0000004ENlQAM"
    }
  }
}]

Output JSON

[{
  "Id": "0hb3L00000000jkQAA",
  "Name": "P-2797",
  "ContactEncounterId": "0ha3L000000001qQAA",
  "StartTime": "2020-06-27T11:00:00.000Z",
  "EncounterDuration": 25,
  "ContactEncounter.Name": "Grocery Shopping 17",
  "ContactEncounter.LocationId": "1313L0000004ENlQAM",
  "ContactEncounter.Id": "0ha3L000000001qQAA",
  "ContactEncounter.Location.Name": "Waitrose",
  "ContactEncounter.Location.LocationType": "Site",
  "ContactEncounter.Location.Id": "1313L0000004ENlQAM"
}]

Answer №1

To delve deeper into the object, a recursion must be created to track the path being taken.

One way to solve this is:

const input = [{
        "Id": "0hb3L00000000jkQAA",
        "Name": "P-2797",
        "ContactEncounterId": "0ha3L000000001qQAA",
        "StartTime": "2020-06-27T11:00:00.000Z",
        "EncounterDuration": 25,
        "ContactEncounter": {
            "Name": "Grocery Shopping 17",
            "LocationId": "1313L0000004ENlQAM",
            "Id": "0ha3L000000001qQAA",
            "Location": {
                "Name": "Waitrose",
                "LocationType": "Site",
                "Id": "1313L0000004ENlQAM"
            }
        }
    }
];

function merge( source, target = {}, ...parents) {
  for (let [key, value] of Object.entries( source ) ) {
    const path = (parents || []).concat( key );
    if (typeof value === 'object') {
      merge( value, target, ...path );
      continue;
    }
    target[path.join('.')] = value;
  }
  return target;
}

console.log( merge( input[0] ) );

Alternatively, you can use Object.assign to assign results of the deeper search into your current object:

const input = [{
        "Id": "0hb3L00000000jkQAA",
        "Name": "P-2797",
        "ContactEncounterId": "0ha3L000000001qQAA",
        "StartTime": "2020-06-27T11:00:00.000Z",
        "EncounterDuration": 25,
        "ContactEncounter": {
            "Name": "Grocery Shopping 17",
            "LocationId": "1313L0000004ENlQAM",
            "Id": "0ha3L000000001qQAA",
            "Location": {
                "Name": "Waitrose",
                "LocationType": "Site",
                "Id": "1313L0000004ENlQAM"
            }
        }
    }
];

function merge( source, ...parents) {
  const mergedValue = {};
  for (let [key, value] of Object.entries( source ) ) {
    const path = (parents || []).concat( key );
    if (typeof value === 'object') {
      Object.assign( mergedValue, merge( value, ...path ) );
      continue;
    }
    mergedValue[path.join('.')] = value;
  }
  return mergedValue;
}

console.log( merge( input[0] ) );

Answer №2

Exploring a different strategy involves utilizing the second parameter and passing the key when searching for an object at a specific level.

const obj = {
  "Id": "0hb3L00000000jkQAA",
  "Name": "P-2797",
  "ContactEncounterId": "0ha3L000000001qQAA",
  "StartTime": "2020-06-27T11:00:00.000Z",
  "EncounterDuration": 25,
  "ContactEncounter": {
    "Name": "Grocery Shopping 17",
    "LocationId": "1313L0000004ENlQAM",
    "Id": "0ha3L000000001qQAA",
    "Location": {
      "Name": "Waitrose",
      "LocationType": "Site",
      "Id": "1313L0000004ENlQAM"
    }
  }
}


function flattenObj(obj, param) {
  let newObj = {};
  for (let key in obj) {
    if (typeof obj[key] === 'object') {
      newObj = { ...newObj,
        ...flattenObj(obj[key], key + '.')
      }
    } else {
      newObj[param + key] = obj[key]
    }
  }
  return newObj;
}


console.log(flattenObj(obj, ''))

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

Using Angular to Apply a Custom Validation Condition on a FormGroup Nested Within Another FormGroup

I am facing an issue with my form validation logic. I have a set of checkboxes that need to be validated only when a specific value is selected from a dropdown. The current validator checks the checkboxes regardless of the dropdown value. Here's the c ...

Selection of Dropdown results in PDF not loading

I am facing an issue with my function that selects a PDF from a dropdown list. Instead of loading and displaying the PDF, it only shows a blank modal. Any suggestions on how to fix this? <li> <a href="">Case Studies</a> <ul clas ...

Require assistance in getting a slider operational

Hello there! I could really use your assistance with this code. I have been trying to make it work using JavaScript, but I'm determined not to incorporate any external JS files. Here is the snippet of JavaScript code I am working with: "use strict"; ...

Learn how to implement a call to 'next()' in Express and Node.js only after successfully creating schemas

I am currently developing an event app, and within my 'Event' schema, I have an array of 'Tag' schemas, allowing each event to be associated with one or more tags. Event: var EventSchema = new Schema({ ... tags: [{ type: Schema.Type ...

Using Django Sessions for User Authentication in React Applications

Not a coding query, but rather a general one: When using default authentication in Django (session authentication), what does the frontend (in my case it's React) require? For instance, upon logging in on the browser via the front end login button, th ...

MUI Alert: Encountered an Uncaught TypeError - Unable to access properties of undefined when trying to read 'light' value

After utilizing MUI to create a login form, I am now implementing a feature to notify the user in case of unsuccessful login using a MUI Alert component. import Alert from '@mui/material/Alert'; The code snippet is as follows: <CssVarsProvide ...

Using an if-else statement in AngularJS

<ng-switch on="MyData.Status"> <p ng-switch-when="2"> <p ng-if="MyData.SomeProp == false"> Message 1 </p> <p ng-if="MyData.SomeProp == true"> Message 2 </p> ...

Looking through a Json file and retrieving data with the help of Javascript

I am currently working on developing a dictionary application for FirefoxOS using JavaScript. The structure of my JSON file is as follows: [ {"id":"3784","word":"Ajar","type":"adv.","descr":" Slightly turned or opened; as, the door was standing ajar.","tr ...

Display a tooltip for ever-changing content

My HTML code displays dynamic rows with information, along with an image link that reveals specific details about the clicked row using the compentence_ID field. echo "<td>".$compi['Competence_ID']."</td>"; ec ...

Embedding a countdown timer in basic HTML code

Attempting to embed the following into an HTML website: The issue I am facing is that when I run it, the timer does not appear. However, when I run it in fsFiddle, I do see the countdown timer. What could be causing this problem? <!DOCTYPE html> & ...

Determining the Right Version of a Framework in npm: A Guide

One common issue I encounter is the uncertainty of which versions of npm, Ionic, and other tools I should have installed. It often goes like this: "Oh, there's a new version of the Ionic CLI out. Let's update." I install CLI v3.9.0. ...

Using JSON Serialization in MVC3

How do I handle JSON serialization for the object being returned as null in my controller? public class CertRollupViewModel { public IEnumerable<CertRollup> CertRollups { get; set; } } public class CertRollup { public decimal TotalCpm { get ...

Tips for validating an email address using ReactJS

I'm currently working on customizing the email verification process for a signup form in ReactJS. My goal is to replace the default email verification with my own validation criteria. Initially, I want to ensure that the entered email address contains ...

Pass the returned variable value from a request.get call to another function in NodeJS Express

I have a situation where I am calling a function that makes a request to get some JSON data and then fills in the variables from my router.get method. The issue I am facing is that the variables are getting their value inside the callFunc function, but wh ...

MUI: The fontFamily property is not able to be overridden by nesting within the

My goal is to have different fonts for different parts of my application using theme nesting. Unfortunately, I discovered that theme nesting doesn't work when it comes to overriding fonts. In my App.js file: import React from "react"; impor ...

Move the DIV element to a static section within the DOM

In my Vue app, I have implemented methods to dynamically move a DIV called 'toolbox' to different sections of the DOM. Currently, the DIV is positioned on the bottom right of the screen and remains static even when scrolling. My goal is to use t ...

After clicking the create button in AngularJS, the ngModel values become empty

My form has been simplified by using ngRepeat to create the input fields. The attributes for each item are defined in my controller. Below is the code for the ModalCtrl: ... $scope.form = [ { label: 'First Name', fieldType: 't ...

Load a script in a specific div using React

Can anyone assist me with loading a script onto a specific component in my React application? Here is the script that needs to be loaded at the bottom-most div within my component: <div id="rexxxx"></div> <script> new carouselI ...

What is the best way to extract a portion of a JSON string?

this.on('success', function(file, responseText) { var theID = JSON.stringify(responseText); alert(theID); window.location.href = ('want to put something here'); }); The ...

AngularJS does not update values properly if there is a style applied to the parent container

I'm struggling to find the best approach to handle this situation. This is how my AngularJS code looks: <span class="something" ng-hide="onsomecondition"> {{value}} </span> .something{ text-align:left; padding:10px;} Issue: The value ...