Is it possible to add dynamically named properties to JavaScript object?

Javascript

Javascript Problem Overview


In JavaScript, I've created an object like so:

var data = {
    'PropertyA': 1,
    'PropertyB': 2,
    'PropertyC': 3
};

Is it possible to add further properties to this object after its initial creation if the properties name is not determined until run time? i.e.

var propName = 'Property' + someUserInput
//imagine someUserInput was 'Z', how can I now add a 'PropertyZ' property to 
//my object?

Javascript Solutions


Solution 1 - Javascript

Yes.

var data = {
    'PropertyA': 1,
    'PropertyB': 2,
    'PropertyC': 3
};

data["PropertyD"] = 4;

// dialog box with 4 in it
alert(data.PropertyD);
alert(data["PropertyD"]);

Solution 2 - Javascript

ES6 for the win!

const b = 'B';
const c = 'C';

const data = {
	a: true,
	[b]: true, // dynamic property
	[`interpolated-${c}`]: true, // dynamic property + interpolation
    [`${b}-${c}`]: true
}

If you log data you get this:

{
  a: true,
  B: true,
  interpolated-C: true,
  B-C: true
}

This makes use of the new Computed Property syntax and Template Literals.

Solution 3 - Javascript

Yes it is possible. Assuming:

var data = {
    'PropertyA': 1,
    'PropertyB': 2,
    'PropertyC': 3
};
var propertyName = "someProperty";
var propertyValue = "someValue";

Either:

data[propertyName] = propertyValue;

or

eval("data." + propertyName + " = '" + propertyValue + "'");

The first method is preferred. eval() has the obvious security concerns if you're using values supplied by the user so don't use it if you can avoid it but it's worth knowing it exists and what it can do.

You can reference this with:

alert(data.someProperty);

or

data(data["someProperty"]);

or

alert(data[propertyName]);

Solution 4 - Javascript

I know that the question is answered perfectly, but I also found another way to add new properties and wanted to share it with you:

You can use the function Object.defineProperty()

Found on Mozilla Developer Network

Example:

var o = {}; // Creates a new object

// Example of an object property added with defineProperty with a data property descriptor
Object.defineProperty(o, "a", {value : 37,
                               writable : true,
                               enumerable : true,
                               configurable : true});
// 'a' property exists in the o object and its value is 37

// Example of an object property added with defineProperty with an accessor property descriptor
var bValue;
Object.defineProperty(o, "b", {get : function(){ return bValue; },
                               set : function(newValue){ bValue = newValue; },
                               enumerable : true,
                               configurable : true});
o.b = 38;
// 'b' property exists in the o object and its value is 38
// The value of o.b is now always identical to bValue, unless o.b is redefined

// You cannot try to mix both :
Object.defineProperty(o, "conflict", { value: 0x9f91102, 
                                       get: function() { return 0xdeadbeef; } });
// throws a TypeError: value appears only in data descriptors, get appears only in accessor descriptors

Solution 5 - Javascript

ES6 introduces computed property names, which allows you to do

let a = 'key'
let myObj = {[a]: 10};
// output will be {key:10}

Solution 6 - Javascript

Here, using your notation:

var data = {
    'PropertyA': 1,
    'PropertyB': 2,
    'PropertyC': 3
};
var propName = 'Property' + someUserInput
//imagine someUserInput was 'Z', how can I now add a 'PropertyZ' property to 
//my object?
data[propName] = 'Some New Property value'

Solution 7 - Javascript

You can add as many more properties as you like simply by using the dot notation:

var data = {
    var1:'somevalue'
}
data.newAttribute = 'newvalue'

or:

data[newattribute] = somevalue

for dynamic keys.

Solution 8 - Javascript

in addition to all the previous answers, and in case you're wondering how we're going to write dynamic property names in the Future using Computed Property Names ( ECMAScript 6 ), here's how:

var person = "John Doe";
var personId = "person_" + new Date().getTime();
var personIndex = {
	[ personId ]: person
//  ^ computed property name
};

personIndex[ personId ]; // "John Doe"

reference: Understanding ECMAScript 6 - Nickolas Zakas

Solution 9 - Javascript

Just an addition to abeing's answer above. You can define a function to encapsulate the complexity of defineProperty as mentioned below.

var defineProp = function ( obj, key, value ){
  var config = {
    value: value,
    writable: true,
    enumerable: true,
    configurable: true
  };
  Object.defineProperty( obj, key, config );
};

//Call the method to add properties to any object
defineProp( data, "PropertyA",  1 );
defineProp( data, "PropertyB",  2 );
defineProp( data, "PropertyC",  3 );

reference: http://addyosmani.com/resources/essentialjsdesignpatterns/book/#constructorpatternjavascript

Solution 10 - Javascript

You can add properties dynamically using some of the options below:

In you example:

var data = {
    'PropertyA': 1,
    'PropertyB': 2,
    'PropertyC': 3
};

You can define a property with a dynamic value in the next two ways:

data.key = value;

or

data['key'] = value;

Even more..if your key is also dynamic you can define using the Object class with:

Object.defineProperty(data, key, withValue(value));

where data is your object, key is the variable to store the key name and value is the variable to store the value.

I hope this helps!

Solution 11 - Javascript

I know there are several answers to this post already, but I haven't seen one wherein there are multiple properties and they are within an array. And this solution by the way is for ES6.

For illustration, let's say we have an array named person with objects inside:

 let Person = [{id:1, Name: "John"}, {id:2, Name: "Susan"}, {id:3, Name: "Jet"}]

So, you can add a property with corresponding value. Let's say we want to add a Language with a default value of EN.

Person.map((obj)=>({...obj,['Language']:"EN"}))

The Person array now would become like this:

Person = [{id:1, Name: "John", Language:"EN"}, 
{id:2, Name: "Susan", Language:"EN"}, {id:3, Name: "Jet", Language:"EN"}]

Solution 12 - Javascript

It can be useful if mixed new property add in runtime:

data = { ...data, newPropery: value}

However, spread operator use shallow copy but here we assign data to itself so should lose nothing

Solution 13 - Javascript

I was looking for a solution where I can use dynamic key-names inside the object declaration (without using ES6 features like ... or [key]: value)

Here's what I came up with:

var obj = (obj = {}, obj[field] = 123, obj)

It looks a little bit complex at first, but it's really simple. We use the Comma Operator to run three commands in a row:

  1. obj = {}: creates a new object and assigns it to the variable obj
  2. obj[field] = 123: adds a computed property name to obj
  3. obj: use the obj variable as the result of the parentheses/comma list

This syntax can be used inside a function parameter without the requirement to explictely declare the obj variable:

// The test function to see the result.
function showObject(obj) {
    console.log(obj);
}

// My dynamic field name.
var field = "myDynamicField";

// Call the function with our dynamic object.
showObject( (obj = {}, obj[field] = 123, obj) );

/*
Output:

{
  "myDynamicField": true
}
*/

Some variations

"strict mode" workaround:

The above code does not work in strict mode because the variable "obj" is not declared.

// This gives the same result, but declares the global variable `this.obj`!
showObject( (this.obj = {}, obj[field] = 123, obj) );
ES2015 code using computed property names in initializer:
// Works in most browsers, same result as the other functions.
showObject( {[field] = 123} );

This solution works in all modern browsers (but not in IE, if I need to mention that)

Super hacky way using JSON.parse():
// Create a JSON string that is parsed instantly. Not recommended in most cases.
showObject( JSON.parse( '{"' + field +'":123}') );
// read: showObject( JSON.parse( '{"myDynamicfield":123}') );
Allows special characters in keys

Note that you can also use spaces and other special characters inside computed property names (and also in JSON.parse).

var field = 'my dynamic field :)';
showObject( {[field] = 123} );
// result: { "my dynamic field :)": 123 }

Those fields cannot be accessed using a dot (obj.my dynamic field :) is obviously syntactically invalid), but only via the bracket-notation, i.e., obj['my dynamic field :)'] returns 123

Solution 14 - Javascript

The simplest and most portable way is.

var varFieldName = "good";
var ob = {};
Object.defineProperty(ob, varFieldName , { value: "Fresh Value" });

Based on #abeing answer!

Solution 15 - Javascript

Be careful while adding a property to the existing object using .(dot) method.

(.dot) method of adding a property to the object should only be used if you know the 'key' beforehand otherwise use the [bracket] method.

Example:

var data = { 'Property1': 1 };

    // Two methods of adding a new property [ key (Property4), value (4) ] to the
    // existing object (data)
    data['Property2'] = 2; // bracket method
    data.Property3 = 3;    // dot method
    console.log(data);     // { Property1: 1, Property2: 2, Property3: 3 }
    
    // But if 'key' of a property is unknown and will be found / calculated
    // dynamically then use only [bracket] method not a dot method    
    var key;
    for(var i = 4; i < 6; ++i) {
    	key = 'Property' + i;     // Key - dynamically calculated
    	data[key] = i; // CORRECT !!!!
    }
    console.log(data); 
    // { Property1: 1, Property2: 2, Property3: 3, Property4: 4, Property5: 5 }
    
    for(var i = 6; i < 2000; ++i) {
    	key = 'Property' + i; // Key - dynamically calculated
    	data.key = i;         // WRONG !!!!!
    }
    console.log(data); 
    // { Property1: 1, Property2: 2, Property3: 3, 
    //   Property4: 4, Property5: 5, key: 1999 }

Note the problem in the end of console log - 'key: 1999' instead of Property6: 6, Property7: 7,.........,Property1999: 1999. So the best way of adding dynamically created property is the [bracket] method.

Solution 16 - Javascript

A nice way to access from dynamic string names that contain objects (for example object.subobject.property)

function ReadValue(varname)
{
    var v=varname.split(".");
    var o=window;
    if(!v.length)
        return undefined;
    for(var i=0;i<v.length-1;i++)
        o=o[v[i]];
    return o[v[v.length-1]];
}

function AssignValue(varname,value)
{
    var v=varname.split(".");
    var o=window;
    if(!v.length)
        return;
    for(var i=0;i<v.length-1;i++)
        o=o[v[i]];
    o[v[v.length-1]]=value;
}

Example:

ReadValue("object.subobject.property");
WriteValue("object.subobject.property",5);

eval works for read value, but write value is a bit harder.

A more advanced version (Create subclasses if they dont exists, and allows objects instead of global variables)

function ReadValue(varname,o=window)
{
    if(typeof(varname)==="undefined" || typeof(o)==="undefined" || o===null)
        return undefined;
    var v=varname.split(".");
    if(!v.length)
        return undefined;
    for(var i=0;i<v.length-1;i++)
    {
        if(o[v[i]]===null || typeof(o[v[i]])==="undefined") 
            o[v[i]]={};
        o=o[v[i]];
    }
    if(typeof(o[v[v.length-1]])==="undefined")    
        return undefined;
    else    
        return o[v[v.length-1]];
}

function AssignValue(varname,value,o=window)
{
    if(typeof(varname)==="undefined" || typeof(o)==="undefined" || o===null)
        return;
    var v=varname.split(".");
    if(!v.length)
        return;
    for(var i=0;i<v.length-1;i++)
    {
        if(o[v[i]]===null || typeof(o[v[i]])==="undefined")
            o[v[i]]={};
        o=o[v[i]];
    }
    o[v[v.length-1]]=value;
}

Example:

ReadValue("object.subobject.property",o);
WriteValue("object.subobject.property",5,o);

This is the same that o.object.subobject.property

Solution 17 - Javascript

Here's how I solved the problem.

var obj = {

};
var field = "someouter.someinner.someValue";
var value = 123;

function _addField( obj, field, value )
{
    // split the field into tokens
    var tokens = field.split( '.' );

    // if there's more than one token, this field is an object
    if( tokens.length > 1 )
    {
        var subObj = tokens[0];

        // define the object
        if( obj[ subObj ] !== undefined ) obj[ subObj ] = {};

        // call addfield again on the embedded object
        var firstDot = field.indexOf( '.' );
        _addField( obj[ subObj ], field.substr( firstDot + 1 ), value );

    }
    else
    {
        // no embedded objects, just field assignment
        obj[ field ] = value;
    }
}

_addField( obj, field, value );
_addField(obj, 'simpleString', 'string');

console.log( JSON.stringify( obj, null, 2 ) );

Generates the following object:

{
  "someouter": {
    "someinner": {
      "someValue": 123
    }
  },
  "simpleString": "string"
}

Solution 18 - Javascript

Yes it is possible. I have achieved using below implementation. for that I am getting array in response which I want in an object as list of attributes.

response = {
  "equityMonths": [
    {
      "id": 1,
      "month": "JANUARY",
      "isEligible": false
    },
    {
      "id": 2,
      "month": "FEBRUARY",
      "isEligible": true
    },
    {
      "id": 3,
      "month": "MARCH",
      "isEligible": false
    },
    {
      "id": 4,
      "month": "APRIL",
      "isEligible": true
    },
    {
      "id": 5,
      "month": "MAY",
      "isEligible": false
    },
    {
      "id": 6,
      "month": "JUNE",
      "isEligible": true
    },
    {
      "id": 7,
      "month": "JULY",
      "isEligible": true
    },
    {
      "id": 8,
      "month": "AUGUST",
      "isEligible": false
    },
    {
      "id": 9,
      "month": "SEPTEMBER",
      "isEligible": true
    },
    {
      "id": 10,
      "month": "OCTOBER",
      "isEligible": false
    },
    {
      "id": 11,
      "month": "NOVEMBER",
      "isEligible": true
    },
    {
      "id": 12,
      "month": "DECEMBER",
      "isEligible": false
    }
  ]
}

here, I want equityMonths as an object and Jan to Dec it's key and isEligible as value. for that we have to use Object class's defineProperty() method which allows to add dynamic property into objects.

code for adding property dynamically to the object.

let equityMonth = new Object();

response.equityMonths.forEach(element => {
    Object.defineProperty(equityMonth, element['month'], {
       value: element['isEligible'],
       writable: true,
       enumerable: true,
       configurable: true
    });
});
console.log("DATA : " + JSON.stringify(equityMonth));

in above code we have array of equityMonths which we have converted as property into the object.

output:

DATA : {"JANUARY":false,"FEBRUARY":true,"MARCH":false,"APRIL":true,"MAY":false,"JUNE":true,"JULY":true,"AUGUST":false,"SEPTEMBER":true,"OCTOBER":false,"NOVEMBER":true,"DECEMBER":false}

Solution 19 - Javascript

A perfect easy way

var data = {
    'PropertyA': 1,
    'PropertyB': 2,
    'PropertyC': 3
};

var newProperty = 'getThisFromUser';
data[newProperty] = 4;

console.log(data);

If you want to apply it on an array of data (ES6/TS version)

const data = [
  { 'PropertyA': 1, 'PropertyB': 2, 'PropertyC': 3 },
  { 'PropertyA': 11, 'PropertyB': 22, 'PropertyC': 33 }
];

const newProperty = 'getThisFromUser';
data.map( (d) => d[newProperty] = 4 );

console.log(data);

Solution 20 - Javascript

Definitely. Think of it as a dictionary or associative array. You can add to it at any point.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLee DView Question on Stackoverflow
Solution 1 - JavascriptGeorg SchöllyView Answer on Stackoverflow
Solution 2 - JavascriptMauricio SoaresView Answer on Stackoverflow
Solution 3 - JavascriptcletusView Answer on Stackoverflow
Solution 4 - JavascriptartgroheView Answer on Stackoverflow
Solution 5 - JavascriptRustyView Answer on Stackoverflow
Solution 6 - JavascriptMaxim SloykoView Answer on Stackoverflow
Solution 7 - JavascriptGabriel HurleyView Answer on Stackoverflow
Solution 8 - JavascriptAnas NakawaView Answer on Stackoverflow
Solution 9 - JavascriptSarveshView Answer on Stackoverflow
Solution 10 - JavascriptFabricioView Answer on Stackoverflow
Solution 11 - JavascriptEdperView Answer on Stackoverflow
Solution 12 - JavascriptMohsenView Answer on Stackoverflow
Solution 13 - JavascriptPhilippView Answer on Stackoverflow
Solution 14 - JavascriptSydwellView Answer on Stackoverflow
Solution 15 - JavascriptSridharKrithaView Answer on Stackoverflow
Solution 16 - Javascripthamboy75View Answer on Stackoverflow
Solution 17 - JavascriptlewmaView Answer on Stackoverflow
Solution 18 - JavascriptSandeep PatelView Answer on Stackoverflow
Solution 19 - JavascriptUmeshView Answer on Stackoverflow
Solution 20 - JavascriptthedzView Answer on Stackoverflow