Dynamically set property of nested object
This function, using the arguments you specified, should add/update the data in the obj
container. Note that you need to keep track of which elements in obj
schema are containers and which are values (strings, ints, etc.) otherwise you will start throwing exceptions.
obj = {}; // global object
function set(path, value) {
var schema = obj; // a moving reference to internal objects within obj
var pList = path.split('.');
var len = pList.length;
for(var i = 0; i < len-1; i++) {
var elem = pList[i];
if( !schema[elem] ) schema[elem] = {}
schema = schema[elem];
}
schema[pList[len-1]] = value;
}
set('mongo.db.user', 'root');
How to set nested object with dynamic keys on javascript
You have to create the nested object before you can create a property in it.
let foo = {}
const key1 = 'a'const key2 = 'b'const key3 = 'c'
foo[key1] = {};foo[key1][key2] = {};foo[key1][key2][key3] = [1, 2];console.log(foo);
Javascript: how to dynamically create nested objects using object names given by an array
function assign(obj, keyPath, value) {
lastKeyIndex = keyPath.length-1;
for (var i = 0; i < lastKeyIndex; ++ i) {
key = keyPath[i];
if (!(key in obj)){
obj[key] = {}
}
obj = obj[key];
}
obj[keyPath[lastKeyIndex]] = value;
}
Usage:
var settings = {};
assign(settings, ['Modules', 'Video', 'Plugin'], 'JWPlayer');
How to create dynamically nested objects and object properties in typescript
Without additional libraries you can either assign properties in multiple steps
const account: any = {};
account.documents = {};
account.documents.bank_account_ownership_verification = {};
account.documents.bank_account_ownership_verification.files = this.file.value;
or nested properties
const account: any = {};
account.documents = { bank_account_ownership_verification: { files: this.file.value } };
Dynamically set property of nested object if they exist. Recreate _.extend
You can try with this 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
}
Here is a working example using the given 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);
access property of nested object based on dynamic string
Since you've used string
for both the property name (field
) and the value (val
), I'm going to assume that you're getting those strings from somewhere that you can't get non-strings from (like form fields). So there are two challenges:
field
could be an invalid property name forFrcCapacity
objects, andval
may not be a valid value for whatever propertyfield
identifies.
To handle this in a mostly-typesafe way, you'll need a function that validates that a key is a valid FrcCapacity
key, such as a type assertion function:
function assertIsValidFrcCapacityKey(key: string): asserts key is keyof FrcCapacity {
switch (key) {
case "id":
case "frcId":
case "capGroupId":
// ...and so on for all the valid property names...
break;
default:
throw new Error(`${key} is not a valid key for FrcCapacity objects`);
}
}
That tells TypeScript that if that function doesn't throw, the key passed in is a valid key for FrcCapacity
objects. Obviously, it's less than ideal that you have to repeat all the property names, but there we are.
Then you have to handle the number
/ CapGroup
thing, which you can hardcode into the function:
periodValueChange(val: string, rowIndex: number, field: string) {
assertIsValidFrcCapacityKey(field);
if (field === "capGroup") {
frcCapacity[rowIndex].capGroup = convertStringToCapGroup(val);
} else {
frcCapacity[rowIndex][field] = +val;
}
}
(In that example I've used unary +
to convert the val
string to a number, but there are other ways; I list the various options and their pros and cons here. I've also left the implementation of convertStringToCapGroup
to you, since I don't know what a CapGroup
is, nor how you're encoding it as a string in your form.)
Related Topics
Split a String by Commas But Ignore Commas Within Double-Quotes Using JavaScript
How to Add Months to a Date in JavaScript
Jquery's .Click - Pass Parameters to User Function
How to Enable Cors Nodejs with Express
How to Get All Selected Values from <Select Multiple=Multiple>
Make Function Wait Until Element Exists
HTML Input Type="Number" Still Returning a String When Accessed from JavaScript
Which Is Better: <Script Type="Text/Javascript">...</Script> or <Script>...</Script>
Why Don't Audio and Video Events Bubble
Html5 Filereader How to Return Result
Add Event Listener on Elements Created Dynamically
How to Implement Routereusestrategy Shoulddetach for Specific Routes in Angular 2
Dynamic Keys for Object Literals in JavaScript
Jquery Submit Form and Then Show Results in an Existing Div