Dynamic Keys for Object Literals in JavaScript

dynamic keys for object literals in Javascript

You can set dynamic keys is with bracket notation:

required.directories[this.applicationPath + "/configs"] = "Application config folder does not exists";

(of course wherever you do this definition, this.applicationPath must exist)

But do you need this.applicationPath in the keys? How do you access theses values? Maybe you can just remove this.applicationPath from whatever value you use to access the properties.


But in case you need it:

You could use an array to initialize the keys if you want to avoid repeating a lot of code:

var dirs = ['configs', 'controllers', ...];
var files = ['init.js', 'controllers/index.js', ...];

var required = { directories: {}, files: {} };
required.directories[this.applicationPath] = "Application " + this.application + " does not exists";

for(var i = dirs.length; i--;) {
required.directories[this.applicationPath + '/' + dirs[i]] = "Application " + dirs[i] + " folder does not exists";
}

for(var i = files.length; i--;) {
// same here
}

Creating object with dynamic keys

In the new ES2015 standard for JavaScript (formerly called ES6), objects can be created with computed keys: Object Initializer spec.

The syntax is:

var obj = {
[myKey]: value,
}

If applied to the OP's scenario, it would turn into:

stuff = function (thing, callback) {
var inputs = $('div.quantity > input').map(function(){
return {
[this.attr('name')]: this.attr('value'),
};
})

callback(null, inputs);
}

Note: A transpiler is still required for browser compatiblity.

Using Babel or Google's traceur, it is possible to use this syntax today.


In earlier JavaScript specifications (ES5 and below), the key in an object literal is always interpreted literally, as a string.

To use a "dynamic" key, you have to use bracket notation:

var obj = {};
obj[myKey] = value;

In your case:

stuff = function (thing, callback) {
var inputs = $('div.quantity > input').map(function(){
var key = this.attr('name')
, value = this.attr('value')
, ret = {};

ret[key] = value;
return ret;
})

callback(null, inputs);
}

How to use a variable for a key in a JavaScript object literal?

{ thetop : 10 } is a valid object literal. The code will create an object with a property named thetop that has a value of 10. Both the following are the same:

obj = { thetop : 10 };
obj = { "thetop" : 10 };

In ES5 and earlier, you cannot use a variable as a property name inside an object literal. Your only option is to do the following:

var thetop = "top";

// create the object literal
var aniArgs = {};

// Assign the variable property name with a value of 10
aniArgs[thetop] = 10;

// Pass the resulting object to the animate method
<something>.stop().animate(
aniArgs, 10
);

ES6 defines ComputedPropertyName as part of the grammar for object literals, which allows you to write the code like this:

var thetop = "top",
obj = { [thetop]: 10 };

console.log(obj.top); // -> 10

You can use this new syntax in the latest versions of each mainstream browser.

Passing in dynamic key:value pairs to an object literal?

EDIT: Use var obj = {}; obj[key] = chunks[i];

Because ECMAScript treats the key in this {key:1} as literal.

object literal dynamic key

Because after setting store[target[method]]=0; you are setting target[method] to be equal to a function, this messes up the value of store[target[method]] and makes it undefined. Looks like you will want to use your copy value on the return:

return {count:store[copy]}; 

Although that doesn't help that the count will still be 0 in this case. This is because you are returning an object in Spy directly {prop: value, ...}, as such you cannot really modify it within the Spy function. Although to get around that define the object {count:store[copy]} as a variable within your constructor (var returnObj = {count:store[copy]};), then return that variable: return returnObj. Now you can update returnObj.count inside [target[method]].

This works because Object's in JavaScript are passed-by-reference.

function Spy(target, method) {  var store={};  var self=this;  var copy=target[method];  store[target[method]]=0;  var returnObj = {count:store[copy]};
target[method]=function(){ returnObj.count+=1; return copy.apply(this,arguments); };
return returnObj; }
var spy = Spy(console, 'error');
console.error('calling console.error');console.error('calling console.error');console.error('calling console.error');
console.log(spy.count);

Creating an object with dynamic keys

Create an object, and set its key manually.

var obj = {}
obj[key] = value

Or using ECMAScript 2015 syntax, you can also do it directly in the object declaration:

var obj = {
[key] = value
}

Dynamic object literal in javascript?

for ( var i = 0, l = arr.length; i < l; ++i ) {
literal[arr[i]] = "something";
}

I also took the liberty of optimising your loop :)

Dynamic key type with other key type in typescript

Ideally, split those off into a sub-object on RecordDto instead of having them directly on RecordDto. (For instance, a tabs property with the type Record<string, {isMove: boolean; tabName: string; }>.) But if you can't or don't want to do that:

Provided you can distinguish the index keys from the other keys based on their name, it will work as you have it with a slight tweak. For instance, your key is a number followed by _tab and none of your other properties fits that pattern, so a template literal type works for the key of the index signature and differentiates those from the other property names:

type RecordDto = {
organizationId?: string;
displayName?: string;
photo?: string | null;
[key: `${number}_tab`]: { isMove:boolean, tabName: string };
// ^^^^^^^^^^^^^^^
};

Playground link

If you're receiving these values as strings and need to use them to index into the type, you'll need to tell TypeScript they're valid for use as index keys. To do that, you can use either a type guard function:

function isValidTabName(name: string): name is `${number}_tab` {
return /*...validation logic...*/;
}

...or a type assertion function:

function assertIsValidTabName(name: string): asserts name is `${number}_tab` {
if (! /*...validation logic...*/) {
throw new Error(`The value "${name}" is not a valid tab key`);
}
}

You use them like this:

function addTable(dto: RecordDto, tabKey: string, isMove: boolean, tabName: string) {
assertIsValidTabName(tabKey);
dto[tabKey] = {isMove, tabName};
}

(You'd use if (isValidTabName(tabKey)) if using the type guard function; the key is valid in the true branch.)

Playground link



Related Topics



Leave a reply



Submit