Adjusting an item according to a specified pathway

I am currently working on dynamically modifying an object based on a given path, but I am encountering some difficulties in the process. I have managed to create a method that retrieves values at a specified path, and now I need to update values at that path. The length of the path should not be a limiting factor, so using prop.prop.prop.prop should still work. For instance:

let dataObj = {
  name: 'Old Name',
  address: {
    state: 'CA',
    timezone: 'America/California'
  }
}

let modifiedValues = {
  'name': 'New Name'
  'address.state': 'FL',
  'address.timezone': 'America/New_York'
}

My goal is to iterate over the second object and utilize the key-value pairs to either update the first object directly or construct a new object with the same structure. Ultimately, I aim to achieve an object as follows:

let dataObj = {
  name: 'New Name',
  address: {
    state: 'FL',
    timezone: 'America/New_York'
  }
}

Additionally, below is the method I currently have for retrieving a value based on a provided path:

getAttributeFromPath(path: string, entity: any): any {
  return path.split('.').reduce((a, b) => a && a[b], entity);
}

Answer №1

If you want to modify the first object by setting an attribute from a path, you can create a customized version of getAttributeFromPath.

I have demonstrated this with a function called setAttributeFromPath, using forEach instead of reduce:

let dataObj = {
  name: 'Old Name',
  address: {
    state: 'CA',
    timezone: 'America/California'
  }
};

let modifiedValues = {
  'name': 'New Name',
  'address.state': 'FL',
  'address.timezone': 'America/New_York'
};

const setAttributeFromPath = (path, entity, value) => {
  const pathParts = path.split('.');
  let obj = entity;
  
  pathParts.forEach((part, index) => {
    if (obj[part]) {
      if (index < pathParts.length - 1) {
        obj = obj[part];
      } else {
        obj[part] = value;
      }
    }
  });
};

Object.entries(modifiedValues).forEach(([key, value]) => {
  setAttributeFromPath(key, dataObj, value);
});

console.log(dataObj);

You may wish to try crafting a more concise one-liner form of setAttributeFromPath using reduce.

Answer №2

For this task, you can utilize the eval function. All you have to do is loop through your modified values and update them accordingly.

let originalData = {
  title: 'Old Title',
  info: {
    category: 'Tech',
    rating: '5 stars'
  }
}

let updatedValues = {
  'title': 'New Title',
  'info.category': 'Business',
  'info.rating': '4 stars'
}

function modifyObject(values, object){
    Object.keys(values).forEach( property => {
        eval(`object.${property} = values[property]`);
    });
}

modifyObject(updatedValues, originalData);
console.log(originalData);

Answer №3

To efficiently organize your data, iterate through each item and check for any values that have a dotted structure. Then, construct a new object with the updated layout:

let revisedValues = {
    'name': 'Brand New Name',
    'address.state': 'California',
    'address.timezone': 'America/Los_Angeles'
};

let formattedValues = {};
for(let entry in revisedValues){
    if(entry.includes('.')){
        let separated = entry.split('.');
        if(separated[0] in formattedValues)
            formattedValues[separated[0]][separated[1]] = revisedValues[entry];
        else{
            formattedValues[separated[0]] = {};
            formattedValues[separated[0]][separated[1]] = revisedValues[entry];
        }
    }else{
        formattedValues[entry] = revisedValues[entry];
    }
}
console.log(formattedValues);

Answer №4

Check out this optimized and streamlined approach to a function that involves assigning values by using the last value as reference:

let dataObj = {
  name: 'Old Name',
  address: {
    state: 'CA',
    timezone: 'America/California'
  }
}

let modifiedValues = {
  'name': 'New Name',
  'address.state': 'FL',
  'address.timezone': 'America/New_York'
}

function setAttributeFromPath(path, entity, value) {
  const final = (path = path.split('.')).pop();
  path.reduce((a, b) => a && a[b], entity)[final] = value;
}

for(const key in modifiedValues) setAttributeFromPath(key, dataObj, modifiedValues[key]);

console.log(dataObj);

The loop operation can be integrated into the function itself utilizing array destructuring in the following manner:

function setAttributesFromPath(pathMap, entity) {
  Object.entries(pathMap).forEach(([path,value]) => {
    const final = (path = path.split('.')).pop();
    path.reduce((a, b) => a && a[b], entity)[final] = 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

clicking on a DIV element

I am trying to trigger a JavaScript function by clicking on a DIV element, but for some reason it is not working as expected. I have gone through various examples provided by the helpful people here, but still can't figure out what I'm doing wron ...

Personalize the jquery autocomplete outcome

I'm currently utilizing jQuery autocomplete along with a remote data source. $( "input#searchbar" ).autocomplete({ source: function( request, response ) { $.ajax({type: "post", mode: "abort", dataType: ...

What would be the optimal type for the second argument of the `simulate` method?

When using the simulate function, I am familiar with code like this: simulate("change", { target: { value: '7' } }); However, if my onChange function requires an object as a parameter, what should I pass in the second argument? interface myObj ...

Dividing an AngularJS module across multiple iFrames on a single webpage

Currently, I am working on a web application that consists of 1 module, 5 pages, and 5 controllers. Each HTML page declares the same ng-app. These pages are loaded within widgets on a web portal, meaning each page is loaded within an iFrame in the portal. ...

Guide on Sending a POST Request via HTTPS in Websites

I am developing a browser extension for Chrome that requires sending a post request to a server using standard HTTP. However, this is causing a mixed content error when I'm on a website that uses HTTPS, and the browser refuses to process my request. ...

I'm facing difficulty in assigning props because of the specific nature of generics in Typescript

My goal is to create a Higher Order Component (HOC) that can control a component which relies on certain props to function properly. To elaborate: I want to build a HOC that takes a component expecting props value and onChange, and modifies it so that the ...

The issue with JQGrid: Inaccurate selection of drop down value when edit type is set to 'select'

I am currently using JQGrid 4.4.4 and have encountered an issue with a column set to edittype = 'select'. While the value displayed in the grid row is correct, the drop-down or combo-box value is being set to the wrong value when editing the row. ...

Development of client and server using socket.io in node.js

I am trying to set up a basic demo using socket.io from http://socket.io The server (app.js) is functioning properly. However, I am encountering issues with the client side: <script src="/socket.io/socket.io.js"></script> <script ...

Enhancing Apollo Cache Updates using TypeScript null checks

Currently, I am utilizing apollo codgen to automatically generate types for my graphql queries in TypeScript. However, I have noticed that the generated types contain numerous instances of null values, leading to an abundance of if checks throughout my cod ...

Need to swiftly modify values of css attributes?

Here is a snippet of the code I am working with: <div></div> <button> Go </button> div { width: 50px; height: 50px; border: 1px solid #ccc; } var bgs = ['red', 'blue', 'yellow', 'green&apo ...

The power of the V8 JavaScript engine: Understanding v8::Arguments and the versatility of function

I have created a Node.js addon that wraps a C++ standard library element std::map<T1,T2>. The goal is to expose this map as a module with two primary functions: Set for adding new key-value pairs and Get for retrieving values by key. I want to create ...

Sending data from a JavaScript variable to PHP within the same page

I've been attempting to transfer a JavaScript variable to PHP within the same page without success. I have tried different codes but none seem to be working as expected. Here is the current code snippet: function init(e){ $('#DeleteDaily' ...

Unusual "visual" phenomenon with autocomplete feature in VUE.js

Can someone review this code snippet? Check out the code here This is a peculiar example of a custom autocomplete VUE component. If you enter a value in one of the fields in Section 1 (like 'Apple'), then click on the Next button, you'll ...

How to set up an Angular ErrorHandler?

Attempted to register an Angular ErrorHandler in this simplified StackBlitz environment, but it seems that it's not capturing the error thrown within the constructor of the HelloComponent. Any insights on this issue? Your opinions? ...

Retrieving data from the <script> tag and transferring it to the t-esc tag within Odoo 12

After attempting to retrieve the current coordinates of a location in Odoo, I successfully obtained longitude and latitude data through an alert generated by the following code: <button onclick="getLocation()">Try It</button> ...

What are some ways I can safeguard my CSS from injected elements?

I have created an HTML widget that is inserted into various websites without the use of iframes. However, I am encountering issues where the CSS of some sites is affecting the appearance of my elements, such as text alignment, underlining, and spacing. Is ...

Use Object.assign to swap out the current state with a new

Why does the React component with state { key: bool } not omit the existing state key from the new state when a different option is clicked? Link to the code var SampleComponent = React.createClass({ getInitialState: function() { return {}; }, ...

Can anyone suggest a simpler method for creating function signatures with multiple conditions?

In my function, the first argument now determines if the function should receive an array or not. This function is similar to Foo type stringF = (arr: false, type: 'str', value: string) => void type numberF = (arr, false, type: 'num&apo ...

Inserting a variable into a JSON string

Within my code, I have a basic variable containing strings that are converted into a JSON object. My goal is to create an input field where a person's name can be entered and added to the text. The current setup looks like this var text = '{"st ...

retrieve the value of a text form using jQuery and its corresponding id

I need help with a basic HTML form that includes jQuery. My goal is to: 1) Retrieve the value into a JavaScript variable. 2) Send it as JSON to a server. Here is the form: <div data-role="main" class="ui-content"> <data=role "form" ...