Create a function that can dynamically assign properties to nested objects if they exist, essentially replicating the functionality of the _

I am trying to achieve the following result dynamically without manually specifying where the matches are located in the Object's properties.

Intended Result

const obj = {
  levelOne: {
    someFun: () => {},
    levelTwo: {
      anArray: [],
      something: 'asas',
      levelThree: {
        stay: 'the same',
        name: 'Set this one!',
      },
    },
  },
}

const updatedObj = {
  ...obj,
  levelOne: {
    ...obj.levelOne,
    levelTwo: {
      anArray: [],
      ...obj.levelOne.levelTwo,
      levelThree: {
        ...obj.levelOne.levelTwo.levelThree,
        name: 'Updated prop!',
      },
    },
  },
}

console.info(updatedObj)
{
 levelOne: {
   someFun: () => {},
   levelTwo: {
     something: 'asas',
       levelThree: {
         stay: 'the same',
         name: "Updated prop!",
       },
     },
   },
 }

Current Progress

const inputOriginal = {
  levelOne: {
    levelTwo: {
        something: 'asas',
        levelThree: {
        name: "Original input!"
      }
    }
  }
}
const newInput = {
  levelOne: {
    levelTwo: {
      levelThree: {
        name: "Updated prop!"
      }
    }
  }
}

const mergeObjects = function(overWrite, original){
    return Object.entries(original).reduce( (acc, [ key, item ]) => {
        if(typeof item === 'object' && overWrite[key]) {
            mergeObjects(overWrite[key], item)
            acc = {
                ...acc,
                [key]: item
            }
        } else if(overWrite[key]) {
            acc = {
                ...acc,
                [key]: overWrite[key]
            }
        }
        return acc
    }, {})
}
const merged = mergeObjects(inputOriginal,newInput) //merged.levelOne.levelTwo.levelThree = "Updated prop!"

However, there seems to be a flaw in my code logic where upon exiting the recursion, it overrides the changed values with the original ones.

Is there a way to create a function that achieves the same as the 'Intended Result'?

Answer №1

One potential solution is to utilize the following function:

const mergeObjects = (obj, updates) => {
  for (const key of Object.keys(updates)) {
    if (updates[key] instanceof Object) Object.assign(updates[key], mergeObjects(obj[key], updates[key]))
  }
  Object.assign(obj || {}, updates)
  return obj
}

Below is a functional example showcasing the usage of the provided objects:

const inputOriginal = {
  levelOne: {
    levelTwo: {
      something: 'asas',
      levelThree: {
        name: "Original input!"
      }
    }
  }
}
const newInput = {
  levelOne: {
    levelTwo: {
      levelThree: {
        name: "Updated prop!"
      }
    }
  }
}

const mergeObjects = (obj, updates) => {
  for (const key of Object.keys(updates)) {
    if (updates[key] instanceof Object) Object.assign(updates[key], mergeObjects(obj[key], updates[key]))
  }
  Object.assign(obj || {}, updates)
  return obj
}

const merged = mergeObjects(inputOriginal, newInput)
console.log(merged);

Answer №2

Have you considered using underscore instead?

_.has(obj, 'l1.l2.l3' ) && _.set(obj, 'l1.l2.l3', 'Now updated')

or

_.has(obj, 'l1.l2' ) && _.set(obj, 'l1.l2.l3', 'Now updated')

You might be able to import just the object sub-package from underscore without needing the whole library.

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 is the best method to clear data in a field following a change in selection in another field?

Currently, I am exploring the functionality of ejTimePicker from the reference site: In my project, I have implemented two select boxes, named textbox1 and textbox2, which store selected times. My goal is to reset the time in textbox2 whenever a different ...

Mysterious and never-ending loop that seems to loop endlessly and eludes my

My prototype includes a method for adding callbacks: /* * Add a callback function that is invoked on every element submitted and must return a data object. * May be used as well for transmitting static data. * * The callback function is supposed to e ...

hover effect with fading transition while mouse is still hovering

Is there a way to create a fade-in/fade-out effect on a div without the mouse needing to leave the area? Let me provide a clearer explanation: When the mouse enters the object The object gradually fades in Then, after a delay, the object fades out while ...

The contents of req.body resemble an empty {}

Does anyone know why the req.body is empty in this code snippet? Even though all form data is submitted, it doesn't seem to be recognized in the req.body. Strangely enough, it works perfectly fine in postman. Take a look at the server-side code: con ...

Enter the variable into the parameter

I'm working with some Javascript code: document.getElementById("Grid").style.gridTemplateRows = "repeat(3, 2fr)"; I'm trying to insert a variable as an argument to modify my CSS style. When I attempt the following: "repe ...

What are some ways I can integrate my Json object into my IONIC app rather than relying on a hardcoded object?

I stumbled upon this IONIC app's services.js file and found an example using a hardcoded object called "employees." Instead of using the hardcoded object, I wanted to use a JSON file. However, my attempt to make this change did not work as expected. I ...

Transforming iframe programming into jquery scripting

Currently, I have implemented an Iframe loading the contents within every 5 seconds. It works well, however, there is a consistent blinking effect each time it loads which can be quite bothersome. I am looking to replace the iframe with a scrolling div so ...

Array of Gross Pay for Employee Payroll

I have been tasked with developing a code that calculates an employee(s) gross pay, with the condition that the hourly pay cannot fall below $8. Despite no visible errors during compilation, my code fails to execute. public static void main(String[] args) ...

The function window.open has been disabled on codepen.io site

My dilemma involves a button designed to open a random Wikipedia page. While the code works perfectly in the CodePen editor, I encounter issues when opening it in full-page view. The problem arises when the log displays 'window.open is disabled'. ...

What is the most effective method for discerning the availability of fresh data?

Many highload websites are able to notify their users of new messages or topics in real-time without the need for page refreshing. How do they achieve this and what approaches are commonly used? There appear to be two main methods: Continuously querying ...

Alerting Users Before Navigating Away from an Angular Page

I am looking to implement a feature in my app that will display a warning message when attempting to close the tab, exit the page, or reload it. However, I am facing an issue where the warning message is displayed but the page still exits before I can resp ...

Phone browsers are not executing the jQuery append function as expected

My Flask application utilizes jQuery to dynamically generate data line by line from a SQLalchemy database. I have a forEach loop set up to create each element based on the size of the database. Strangely, this method works flawlessly on all desktop browser ...

Utilizing a Chrome profile is ineffective in WebdriverIO

Instead of dealing with signing in every time, I prefer pre-signing in on my profile. Even though I am using the code below, it's still not loading in the specified profile. What can I do to resolve this issue? const browser = await remote({ capabi ...

I encountered an issue when trying to launch my React application, as the CMD displayed an npm error message stating 'npm error! missing script:start'. Can someone offer assistance with this problem?

view image details Despite spending countless hours searching through past responses and attempting to resolve this issue, I have been unsuccessful. Upon entering 'npm create-react-app' in the terminal and navigating to the correct directory, I ...

Developing a personalized camera feature using ReactJS

After searching for a suitable npm library to create a custom camera component within my ReactJS project, I came across an article providing detailed information at this link. However, I am facing challenges in converting the existing pure JavaScript code ...

Testing NestJS Global ModulesExplore how to efficiently use NestJS global

Is it possible to seamlessly include all @Global modules into a TestModule without the need to manually import them like in the main application? Until now, I've had to remember to add each global module to the list of imports for my test: await Tes ...

acquiring jQuery object property tied to a model-bound element

I have a viewmodel that contains a list of objects which I am currently iterating through. Each object has a specific class associated with it. My objective is to open up the item for viewing upon clicking on it. However, I am unsure of how to retrieve the ...

Is a specific format necessary for express next(err) to function properly?

Recently, while working on my express sub app that utilizes the http-errors module, I encountered an interesting issue. When passing new Forbidden() to the next() callback, it seemed to vanish without triggering any callbacks. However, passing new Error() ...

The Angular JavaScript code displays the message variable in the web browser

When using Angular JavaScript, the browser displays {{message}}. I have tried multiple approaches but it still doesn't work as expected. var myApp=angular.module("mod",[]); myApp.controller("con", function($scope){ $scope.message = "hhhhhhhh"; }); ...

Adjust the size of the text within the div element as needed

Here is my code on jsFiddle where I am dynamically changing the text font to fit in the div. Everything is working perfectly fine. Currently, the text is within a span element, but I would like to remove the span and have the same functionality. However, w ...