What is the most effective method for converting all the keys in a nested array of objects to camel case?

I'm looking to convert all keys of my array of objects into camelCase using TypeScript. Here is the data I have:

[
    {
       "Name":"Custom property",
       "Details":{
          "Address":"Huston",
          "Price":"1000000",
       },
       "Contact":{
          "Global":"3432432",
          "Local":"432423423"
       },
    },
    {
       "Name":"Myproperty",
       "Details":{
          "Address":"Huston",
          "Price":"10000001",
       },
       "Contact":{
          "Global":"34324323",
          "Local":"4324234233"
       },
    },
]

Although I attempted the code below, it only returns a new dictionary with the details. How can I fix this issue?

const newObjOptions = options.map((obj: any) =>
    Object.fromEntries(
      Object.entries(obj).map(([k, v]) => [_.camelCase(k), v])
    )
  );
  const newObjDetailsOptions = newObjOptions.map((obj: any) =>
    Object.fromEntries(
      Object.entries(obj.details).map(([k, v]) => [_.camelCase(k), v])
    )
  );

Answer №1

Your code is effective because when you log both newObjOptions and newObjDetailsOptions, you'll notice that the top-layer of keys is indeed camel-cased.

However, the issue arises from the fact that your code does not verify if the object contains any nested objects.

const newObjOptions = options.map((obj) =>
  Object.fromEntries(
    // You need to check if the value of `v` is an object to camel-case it as well
    Object.entries(obj).map(([k, v]) => [_.camelCase(k), v])
  )
)

To address this issue, you can make modifications to your code like so:

// Check if `v` is an object and apply camel casing recursively
const camelCaseEntry = ([k, v]) => [_.camelCase(k), typeof v === 'object' ? camelCaseObject(v) : v]

const camelCaseObject = obj => Object.fromEntries(
  Object.entries(obj).map(camelCaseEntry)
)

const newObjOptions = options.map(camelCaseObject)
console.log(newObjOptions)

This modification works well with your example, but it may fail if the object contains an array. To handle this scenario, you can implement a simple recursive function, like this:

/**
 * Returns a new object with all keys in camel case, handling nested arrays and objects
 */
function camelCaseObject (object) {
  if (Array.isArray(object)) {
    return object.map(camelCaseObject)
  }
  if (typeof object === 'object') {
    const entries = Object.entries(object)
    return Object.fromEntries(entries.map(transfromEntry))
  }
  return object

  function transfromEntry ([k, v]) {
    return [
      _.camelCase(k),
      typeof v === 'object' ? camelCaseObject(v) : v
    ]
  }
}

Answer №2

Even though the response provided by kill was accepted, I encountered two limitations when attempting to implement it internally.

  1. The solution is not adaptable for all scenarios.
  2. It lacks the capability to handle null values (resulting in a function that never returns if a nested array contains any null values)

Let's create a versatile function that can handle null values effectively:

const objectify = (transformFn: (key: string) => string) => (object: object): object => {
  const transform = ([k, v]: [string, any]) => [
    transformFn(k),
    typeof v === 'object' ? objectify(transformFn)(v) : v
  ]

  if (Array.isArray(object)) {
    return object.map(objectify(transformFn))
  }

  if (typeof object === 'object' && object !== null) {
    const entries = Object.entries(object)
    return Object.fromEntries(entries.map(transform))
  }

  return object
}

export default objectify

Now let's apply camelCase using the objectify function:

import { camelCase } from 'lodash'
import objectify from './objectify'

const camelify = <T extends object> (object: T): object => objectify(camelCase)(object)

export default camelify

To utilize this function, simply pass your objects as parameters: import camelify from './camelify'

const object = camelify({hello_world: 'value'}); // becomes {helloWorld: 'value'}

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 are the best techniques for creating animations in AngularJS?

I've been trying to figure out how to animate in AngularJS by searching online, but I haven't found a perfect solution yet. html <span class="sb-arrow down" ng-click="hideSampleList($event)"></span> ...

creating a versatile axios function through object decomposition

Attempting to create a reusable axios function in my NodeJS project by parsing an object for multiple requests, and using the result of one request in subsequent ones. Previously hardcoded and chained axios requests, I need a more dynamic solution as the ...

Using Volley to display a ListView

I am attempting to establish a connection between SQL Server and Android Studio using JSON with the code provided below. While I do not encounter any errors in Android Studio, testing the application on my phone results in an "Error in connection" message. ...

``Is there a way to access the $attrs data of child DOM elements from within a controller?

Imagine having a controller and multiple children DOMs each with their unique data attributes. <!DOCTYPE html> <html ng-app="plunker"> <head> <meta charset="utf-8" /> <title>AngularJS Plunker</title> < ...

JavaScript can be used to open several tabs simultaneously within a single browser window

Looking to open multiple tabs in the main browser? Check out this code snippet: function openSM() { window.open("http://www.google.com","_blank"); window.open("http://www.yahoo.com","_blank"); window.open("http://www.bing.c ...

Ways to incorporate vector .svg images into a D3js tree diagram

var treeData = [ { "name": "Top Level", "parent": "null", "remark":"yes", "children": [ { "name": "Level 2: A", "parent": "Top Level", "remark":"yes", "children": [ { "name": "So ...

Creating a worldwide object in JavaScript

I am trying to create a global object in JavaScript. Below is an example code snippet: function main() { window.example { sky: "clear", money: "green", dollars: 3000 } } However, I am unable to access the object outside th ...

Sorting through names within a nested array based on specific criteria

I have been struggling to filter by item name for the past day and haven't been successful. The issue lies in my attempt to use a sample array for filtering. While I am able to filter by category successfully, the same cannot be said for filtering by ...

Is it true that Javascript does not allow for saving or outputting actions?

After coming across this question, I discovered a way to extract a specific element from a Google translate page using Javascript. However, I also learned that it is nearly impossible to directly save something to the clipboard in Javascript without user i ...

Developing a user authentication system with TowerJS

As a front-end designer/developer with limited MVC experience, I am looking to create a login form using TowerJS. Following the documentation, my app includes a model named "User": class App.User extends Tower.Model @field "email", type: "String" @fie ...

Generate a dynamic jqplot chart using data retrieved from a variable and JSON data

I'm struggling with loading data into a jqplot chart via variables as it only displays the first value. I am puzzled as to why this is happening. JavaScript: $(document).ready(function () { var sin = [[20, 10, 0, 10, 15, 25, 35, 50, 48, ...

Set a timeout for a single asynchronous request

Is there a way to implement a setTimeout for only one asynchronous call? I need to set a timeout before calling the GetData function from the dataservice, but it should be specific to only one asynchronous call. Any suggestions? Thank you. #html code < ...

Using nodemailer to send an email with a dynamic variable that holds the HTML content

I am attempting to send a variable containing HTML code from a Vue component using the POST method. My technology stack includes TypeScript, Nuxt.js, Node.js, and Vue.js. const order_list = document.querySelector('table') as HTMLInputElement | n ...

What is the best way to trigger a random quote to load from an API in ReactJS using an event like onLoad or another method?

I am currently working on developing a random quote generator. Below is the code I have written so far: import React from "react"; import "./App.css"; function App() { const [quote, setQuote] = React.useState({ text: "" ...

Utilizing Facebook's UI share URL parameters within the Facebook app on mobile devices

Encountering an issue with the Fb ui share functionality on certain smartphones Here is the function: function shareFB(data){ FB.ui({ method: 'share', href: data, }, function(response){}); } Implemented as follows: $urlcod ...

The Console.log function first displays an Object, and then changes to display an Array containing a single object when clicked

When I utilize MobX to call an observable within my React component, something peculiar happens. Upon console logging the observable, initially it appears as an Object. However, upon clicking on it, the object transforms into an Array for that one particul ...

Changing Powershell into Nested Json

After spending several days attempting to solve a particular issue without success, I am turning to you for help or guidance. I am currently working on a PowerShell script that generates service accounts in Active Directory and then stores the username an ...

How to italicize a portion of output using JavaScript

There are numerous inquiries on the internet and on this site regarding how to make italic fonts, however, none specifically address how to italicize only a section of a string. In my scenario, I have a form where I input the book title, author's nam ...

Is it possible for my WebDriver script to detect an event triggered by the webpage?

Is it feasible for my WebDriver script to carry out specific tests after a particular event is triggered on the webpage? Within the WebDriver script, I envision some form of event listener: document.addEventListener("hello", function(){ console.log(" ...

The expected functionality of sending files via ajax is not happening as anticipated

I am having issues with passing file data along with other inputs to my ajax function. Despite my best efforts, the server is not receiving the files. I'm fairly new to using ajax and Jquery. Below is the code snippet of what I have attempted so far. ...