Ways to change attributes of deeply embedded objects?

Imagine having a complex object with nested properties like this:

const obj = {
    Visualization: {
      Lower: [{ name: "Part", selectedValue: "60-000" }],
      Upper: [{ name: "Part", selectedValue: "60-000" }],
    },
    Holder: {
      Lower: [
        { name: "Part", selectedValue: "30-000" },
        { name: "Project Name", selectedValue: "45-000" },
      ],
      Upper: [
        { name: "Part", selectedValue: "22-000" },
        { name: "Project Name", selectedValue: "25-000" },
      ],
    },
  };

If you wish to update all selectedValues in one go to be "0", the desired outcome should look like this:

  {
    Visualization: {
      Lower: [{ name: "Part", selectedValue: "0" }],
      Upper: [{ name: "Part", selectedValue: "0" }],
    },
    Holder: {
      Lower: [
        { name: "Part", selectedValue: "0" },
        { name: "Project Name", selectedValue: "0" },
      ],
      Upper: [
        { name: "Part", selectedValue: "0" },
        { name: "Project Name", selectedValue: "0" },
      ],
    },
  }

Is there a way to achieve this efficiently?

Appreciate any guidance!

Answer №1

function recursiveDeepSet(object, keyName, keyValue) {
    Object.keys(object).forEach(currentKey => {
        if (currentKey === keyName) {
            object[currentKey] = keyValue;
            return;
        }

        if (Array.isArray(object[currentKey])) {
            object[currentKey].forEach(item => {
                recursiveDeepSet(item, keyName, keyValue);
            });
            return;
        }

        if (typeof object[currentKey] !== 'object') {
            return;
        }

        recursiveDeepSet(object[currentKey], keyName, keyValue);
    });
}

JSFiddle: https://jsfiddle.net/713vfdrg/

Answer №2

For a recursive solution to updating the original object, follow these steps:

If the data is in an Array format, iterate through each object and set the selectedValue to 0. This will update all keys within the arrays.

If the data is not an array, it must be an object, so loop through the keys and recursively drill down into the object structure for each key.

The function provided assumes that the data follows the specific format shown above.

const obj = {
    Visualization: {
        Lower: [{ name: "Part", selectedValue: "60-000" }],
        Upper: [{ name: "Part", selectedValue: "60-000" }],
    },
    Holder: {
        Lower: [
            { name: "Part", selectedValue: "30-000" },
            { name: "Project Name", selectedValue: "45-000" },
        ],
        Upper: [
            { name: "Part", selectedValue: "22-000" },
            { name: "Project Name", selectedValue: "25-000" },
        ],
    },
};

function updateSelectedValue(obj, keyToUpdate, valueUpdate) {
    if(Array.isArray(obj)){
        obj.forEach((content, idx) => {
            if(obj[idx][keyToUpdate]){
                obj[idx][keyToUpdate] = valueUpdate;
            }

        })
        return;
    }

    const keys = Object.keys(obj);
    for(const key in obj){
        updateSelectedValue(obj[key], keyToUpdate, valueUpdate);
    }
}

updateSelectedValue(obj, "selectedValue", 0)
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

What are the steps to implement background synchronization in place of making fetch requests upon UI changes?

Consider this scenario: A straightforward web application with a comments feature. In my view, when a user submits a comment, the following steps would typically unfold: Show UI loader; Update the front-end state; Send a fetch request to the API to post ...

How can I retrieve the selected value from an Angular 2 dropdown menu when it changes, in order to utilize it within a function?

I am currently working on creating a dropdown menu with multiple options. When a user selects an option, I need to make an API call that requires an ID parameter. Inside my component.ts file, I have defined an array containing the values like this: valu ...

Tips for sending an optional parameter to @Directives in Angular 2 using TypeScript

Here is a helpful guide on passing parameters to Angular 2 directives. <p [gridGroup]="gridGroup"></p> My goal is to have the parameter as optional so that it doesn't have to be included in every class referencing the html source. Curre ...

Retrieve an array of existing fields in MongoDB by comparing a collection with an array of objects

I'm a newbie when it comes to Mongo and I'm attempting to compare an array with a collection of documents, returning a list of matching records. Let me break it down:First Array I have a collection (user) with the following documents: > db. ...

Concealing Components using Angular's ng-change Feature

I need help displaying or hiding an element in a form using ng-change or any other method you suggest. Here is the HTML snippet I am working with: <div ng-app ng-controller="Controller"> <select ng-model="myDropDown" ng-change="changeState( ...

Arrow functions in ECMAScript 6

var createTempItem = id => ({ id: id, name: "Temporary Product" }); I understand that the arrow function above is the same as: var createTempItem = function(id) { return { id: id, name: "Temporary Product" }; }; However, I am ...

What could be the reason for the mismatch in size between the downloaded file in Express.js and the file size on the server?

My code using express.js is quite simple: app.get("/download", download); and export let download = async (req: Request, res: Response) => { const file = "/tmp/my-file.zip"; res.download(file); } The client-side code is also straightforward: im ...

Is it possible to pass a class method to an onClick event from within the render method in ReactJS?

Excuse my lack of experience, but I haven't been able to find a solution to this yet. I am attempting to utilize a class method as a callback for the onClick event in my JSX. Below is the code for my App component: import React from 'react&apo ...

Mastering Yii2: Implementing Javascript Functions such as onchange() in a View

One of the elements in my project is a checkbox: <div class="checkbox"> <label> <?= Html::checkbox('chocolate', false) ?> Chocolate </label> </div> In addition to that, I also have a span ta ...

What is the best way to configure input fields as readonly, except for the one being actively filled by the user

Is there a way to make all input fields readonly except the one that the user is trying to fill data into? After the user loads the page index.php and attempts to input data into, for example, <input id="edValue2" ...>, I want to set all input field ...

A guide to turning off tab discarding in Google Chrome with JavaScript

Is there a way to prevent Chrome from discarding tabs on chrome://discards/ using JavaScript so that the tab remains open even after closing the page or browser? I am aware that this can be achieved with an extension, but I am interested in creating my o ...

Unlocking the Power of Transition: Effortlessly Submitting a Form Post

After the modal finishes fading out, I want my form to be submitted and sent to the email file "refreshform.php". However, currently after the modal fades out, the form does not submit or post anything to the PHP file for sending the email. It simply fades ...

Retrieve the user information from Auth0 within the NestJS application

I am currently working on implementing Auth0 authorization in NestJS, but I am unsure of how to retrieve the user's data within the callback URL handler. In a normal express function, this issue could be resolved using the following code. The passpor ...

Material design for Angular applications - Angular Material is

Recently, I decided to explore the world of Angular and its accompanying libraries - angular-material, angular-aria, and angular-animate. I'm eager to experiment with this new styling technique, but it seems like I've hit a roadblock right at the ...

What are the advantages of utilizing buffer geometries in Three.js?

I have experience using both BufferGeometry and Geometry, so I feel comfortable with either. Even when I need to make frequent modifications, I tend to lean on BufferGeometry because although the code is more verbose, it's not overly complex. Can you ...

What is the best way to design a grid with various squares in React Native?

Here's the design I aim to achieve: I am looking to implement the above layout in react native and ensure it is responsive on all screen sizes. I attempted using flexbox but couldn't figure out how to make the boxes square shaped. The code provi ...

How can I apply a class to a list item when clicked using Vue.js and a template component generated by v-for loop?

I'm struggling to add an active class to a list item in a template component when it's clicked, making sure that only one item can have the class at a time. I've attempted different solutions such as passing a new data object on click and r ...

Is there a method similar to insertBefore that works with arrays and/or HTMLCollections?

Is there a vanilla JavaScript or jQuery function that works like Node.insertBefore(), but for arrays and/or HTMLCollections? An example of what I'm looking for: var list = document.getElementsByClassName("stuff"); var nodeToMove = list[0]; var other ...

BOOTSTRAP: changing the layout of panels in various sizes for mobile devices

I'm struggling with how to reorganize my panels on mobile devices. Each panel has a different size. Please refer to the attached screenshot for the page layout on large screens (col-lg): https://i.sstatic.net/xcqaT.png EDIT: The layout on large scre ...

Is Nuxt's FingerprintJS Module the Ultimate Server and Client Solution?

I am currently using fingerprintJS in my NuxtJS+Firebase project VuexStore. When I call the function on the client side, I can retrieve the Visitor ID. However, I am encountering issues when trying to use it on the server side, such as in nuxtServerInit. ...