Update a nested object key by concatenating key names with "." to create a string

Imagine having this specific object structure:

var obj = {
  level1 :{
    level2: {
      level3: {
        title: "champion"
      }
    }
  }
}

Now the goal is to update the title key using a provided string (note that it's a string, not an actual variable) like so:

let myString = "level1.level2.level3.title"; // please note that the value of myString is fetched dynamically

One possible method could be:

obj[myString] = "ultimate-champion";

Sadly, the above approach doesn't produce the desired outcome.

Furthermore - there are instances where an undefined object needs to be addressed by defining it with a new empty object.

For instance, If starting off with the following object:

var obj = {
  level1 : {}
  }
}

The objective remains the same: altering the obj in order to reach level3.winner as previously shown.

Quick reminder:

obj[myString] = "ultimate-champion";

How can this be accomplished?

Answer №1

Success!

const data = {
   // section1: {
    //     subsection1: {
    //         subsubsection1: {
    //             title: "champion"
    //         }
    //     }
    // }
}

const myValue = "section1.subsection1.subsubsection1.title"; // note - myString value is retrieved dynamically 

const newTitle = 'ultimate-champion'

myValue.split('.')
    .reduce(
        (acc, curr) => {
            if (acc[curr] === undefined && curr !== 'title') {
                acc[curr] = {}
            }

            if (curr === 'title') {
                acc[curr] = newTitle
            }

            return acc[curr]
        }, data
    );

console.log(data) // {"section1":{"subsection1":{"subsubsection1":{"title":"ultimate-champion"}}}}

This approach does not rely on external libraries, ensuring a lightweight application.

Answer №2

Utilized the method "reduce" to accomplish the desired outcome. Developed a function called "updateValue" that allows you to input obj - object to modify, str - property path to change, and value - value to assign at the property path

var obj1 = {
  level1 :{
    level2: {
      level3: {
        title: "winner"
      }
    }
  }
}

var obj2 = { level1: {} }

var obj3 = {
  level1 :{
    level2: {
      level3: {
        title: "winner"
      }
    }
  }
}

function updateValue(obj, str, value) {
let props = str.split('.'), arrIndex = -1
props.reduce((o,d,i) => ( 
                         arrIndex = d.indexOf('[') > -1 && d[d.indexOf('[') + 1],
                          arrIndex && (d = d.slice(0, d.indexOf('['))),
                           i == props.length - 1 
                              ? o[d] = value 
                              : (o[d] = o[d] || {}, (arrIndex && (Array.isArray(o[d]) || (o[d] = [o[d]]))), arrIndex && o[d][arrIndex] || o[d])
                        )
                , obj)
}

updateValue(obj1, 'level1.level2.level3.title', 'abcd')
updateValue(obj2, 'level1.level2.level3.title', 'abcd')
updateValue(obj3, 'level1.level2[0].title', 'abcd')

console.log(obj1)
console.log(obj2)
console.log(obj3)

Answer №3

A practical way to achieve this is manually by iterating through the object structure and generating new objects whenever needed on the path to the target key:

const updateField = (o, path, entry) => {
  path = path.split(".");
  let curr = o;
  
  while (path.length > 1) {
    const dir = path.shift();    
    const parent = curr;
    curr = curr[dir];

    if (undefined === curr) {
      parent[dir] = {};
      curr = parent[dir];
    }
  }
  
  if (path.length === 1) {
    curr[path.shift()] = entry;
  }
  
  return o;
};

var obj = {
  level1 : {
    level2: {
      level3: {
        title: "winner"
      }
    }
  }
};

console.log(JSON.stringify(updateField(obj, "level1.level2.level3.title", "super-winner"), null, 2));
console.log(JSON.stringify(updateField({}, "level1.level2.level3.title", "super-winner"), null, 2));

Answer №4

To efficiently set values in an object, you can utilize the .set function provided by the lodash library. Check out the documentation here: https://lodash.com/docs#set

For example, you can use the following syntax:

_.set(obj, 'level1.level2.level3.title', 'super-winner');

Alternatively, you can achieve the same result using ES6 syntax:


var str = 'level1.level2.level3.title';
str.split('.').reduce((p, c, index) => {
    if (index === str.split('.').length - 1) {
        if (typeof p[c] !== "object") {
            p[c] = 'super-winner'
        }
        return p[c];
    } else {
        if (!p[c] || typeof p[c] !== 'object') {
            p[c] = {};
        }
        return p[c];
    }
}, obj)

console.log(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

Choosing between radio buttons either horizontally or vertically within a table

Here is the markup I am working with: <table> <tr> <td><input type="radio" name="radio"></td> <td><input type="radio" name="radio"></td> <td><input type="radio" name="radio"></ ...

Tips for choosing or moving to an iframe

What is the best method for choosing or transitioning to an Iframe (as the currently targeted document) using Selenium webdriver in Firefox? Are there alternative approaches for selecting an iframe with or without webdriver? driver.switchTo.frame("Frame ...

Prevent clicking on a div using Jquery

Imagine I have a simple click event set up for an HTML div element. When the div is clicked, it should trigger a fadeToggle effect. Inside that div, there is another nested div with its own click event. Upon clicking this inner div, it is supposed to do s ...

Webpack is failing to load the logo PNG image file

Is there a way to make the logo png file visible on the webpage? I have been encountering issues with loading the image while other elements like HTML, css, and fonts are loading properly when the web pack is started. List of Error Messages: Refused to a ...

Can you explain the purpose of the _app.js and _document.js files in Next.js? What is the significance of using an underscore (_) in Next.js?

After using npx create-next-app to create a next.js app, I noticed that there are 2 JavaScript files named app and document in the pages directory with an initial underscore. What is the purpose of this naming convention? The files appear like this: ▼ p ...

What is the best way to style an icon in CSS?

I am facing an issue with the following code snippet: <span class="stars">★★☆☆☆ </span> My objective is to style the empty stars differently, but I am unsure how to specifically target them. The following CSS rule does not produc ...

Configure markers on Google Maps

I've been attempting to integrate my markers into Google Maps, but I'm stuck on how to use the following: map.fitBounds(latlngbounds); Any ideas on how I can implement this easily? Below is the code I have so far: <script type="text/javas ...

Executing a class function within the ajax success method

I am attempting to set a variable inside the success callback of an AJAX call. I understand that in order to assign the value, I need to use a callback function. However, I want that function to be within the class. Is it feasible to implement something li ...

Can a new EJS file be generated using the existing file as a template?

I am in the process of building a website navbar and I am curious about how to automatically inject code from one ejs file into another ejs file. In Python's Flask framework, this is accomplished using the principle of {% block title%} and in another ...

Retrieve the selected value from a radio button

I am attempting to display the chosen value in an input field when a radio button is selected. However, the functionality seems to be broken when I include bootstrap.min.js. You can find the code on JSFiddle. $('input:radio').click(function() ...

RequireJS is timing out while loading the runtime configuration

I keep encountering a load timeout error with my run-time configuration, specifically with common.js. Although I have set the waitseconds value to 0 for files loaded from common.js, the loadTimeout issue persists for common.js itself. index.html <scr ...

Identify the page search function to reveal hidden content in a collapsible section

Our team has implemented an expandable box feature on our wiki (in Confluence) to condense information, using the standard display:none/block method. However, I am looking for a way to make this work seamlessly with the browser's find functionality. S ...

Tips for preventing real-time changes to list items using the onchange method

I am facing an issue with a list of items that have an Edit button next to them. When I click the Edit button, a modal pops up displaying the name of the item for editing. However, before clicking the save button, the selected item in the list gets changed ...

Accessing Private Files with Signed URLs from AWS S3

Issue: The challenge is to securely allow users to upload a file and retrieve it later. The files are stored in private Buckets and objects using S3 pre-signed URLs for uploading. However, fetching the file poses a problem as the signed URLs expire after ...

The concept of CSS "preload" animation

When working with CSS, I encountered an issue with lag while loading 24 different mask images for a transition effect. To address this, I tried using a div called "preload" to cache the images and prevent lag on playback: <div class='trans' s ...

Handler for stack trace errors and error handling for promises

Introducing my customized error handling function: function onError(message, source, lineno, colno, error) { sendRequestToSendMail(arguments) } window.onerror = onError In addition to that, I have asynchronous tasks utilizing promises and I aim to captur ...

Click on the print icon in the modal window

I have been working on a receipt generator for a client. The client can add payment receipts using the "Add" button, and upon submission, they have the option to convert it to PDF or print it. However, there seems to be an issue with printing as the text f ...

Top solution for maintaining smooth navigation across web pages

As I dive into the world of web development, I find myself intrigued by the idea of reusing navigation and banners across multiple web pages. However, despite my research efforts, I have yet to come across a definitive answer. My objective is simple: The ...

Issue with AJAX communication with C# backend

Currently, I am facing an issue where I am unable to pass information back to the backend code, specifically a user-selected name from a list. I attempted to set the data VN to an object and pass that, but it resulted in errors. It seems that the informati ...

The proper way to implement global scripts in Next.js

I am currently working on implementing a global fade-in animation for all components in my application. By adding the className "fadeIn" to each element and setting the default opacity to 0, I then utilize JavaScript to change it to 1 when the element is v ...