Access internal Property Name to Compute New Property in ES6 [duplicate] - javascript

This question already has answers here:
Self-references in object literals / initializers
(30 answers)
Closed 7 years ago.
I have object. I want to add properties but I want to compute the suffix for all properties in my object during definition.
var myObject = {
foo: "bar",
[ "prop_" + "Access foo property: foo" ]: 42
};
Below is my expected output:
{
foo: "bar",
prop_bar: 42
}
It's not the case that i'm unable to achieve it. i can able to achieve by the below snippet and its working fine but i want this to be done during declaration.
let myObject = {
foo: "bar"
};
myObject[ "prop_" + myObject['foo'] ] = 'hello'
Note to Reviewers: I have already reviewed the below questions.
Is there a shorthand for this in ES6/ES7?
ES6 Object Literal Property Value Shorthand
How to use ES6 computed property names in node / iojs?
ES6 Computed (dynamic) property names
I feel that there will be better solution than above approach, below are my questions.
What is best approach for this scenario?
How many ways we can achieve this ?
Its not possible during declaration ?

You can create factory function to do this, e.g.:
const create = v => ({
foo: v,
["prop_" + v]: 42
});
let myObject = create("bar");
or inline:
let myObject = (v => ({
foo: v,
["prop_" + v]: 42
}))("bar");

Related

How to get value from object using string of object path in typescript without using eval? [duplicate]

This question already has answers here:
Accessing nested JavaScript objects and arrays by string path
(44 answers)
Closed 29 days ago.
In JS/typescript, lets say I have an object like this
var obj = {
a: {
b:{
c:1
}
}
}
And I have a string "b.c". How can I evaluate this using only those variables and get the value 1 from the object without using hacks like eval since typescript would complain.
Thanks
It I understood you question, the keys are known, if so you can use the '[]' to access it :
const a = b.c
is the same thing as
const a = b['c']
but in the second case you can of course use a variable.
Applying this to your object, it would look something like this :
const obj = {
a: {
b: {
c: 1
}
}
}
const outerKey = 'a'
const middleKey = 'b'
const innerKey = 'c'
const value = obj[outerKey][middleKey][innerKey]
console.log(value)
Hope it helped you !

Add or avoid adding a property in an object depending on a boolean within the object itself [duplicate]

This question already has answers here:
Update only non-empty fields | Object spread
(2 answers)
In JavaScript, how to conditionally add a member to an object?
(29 answers)
Closed 4 years ago.
Basically I wonder if I could avoid adding a property into an object if a variable is false but from inside the object. So let's say I have this object:
var obj = { foo: 'bar', bar: 'foo' };
Now I want to rewrite the same object but I only want to add the second property if a new variable, which is a boolean, is true.
The problem is how could I do this for example with a ternary operator like this:
var add = false;
var obj = {
foo: 'bar',
(add ? bar: 'foo': null)
};
What I want to avoid is to have this:
...
bar: ( add ? 'foo' : undefined )
Because I don't want to have the bar index in case add == false. Also the assignament must be inside to object ( that's the question about, if it's posible ) because something like this is not what I'm looking for:
...
if (!add) delete obj.bar; // This would be after the creation of the whole object
Work arounds
Obviously this can be achieved in many ways, but I haven't found any that is done inside the object itself. I could use a ternary operator and having two objects like this:
var obj = add ? {
foo: 'bar',
bar: 'foo'
} : { foo: 'bar' };
But this would lead to having duplicated code ( when the object has more properties ).
Edit I'd say that my question is slightly different from the duplicates since my question refers to do it inside the object not after its declaration nor anything that isn't between var obj = { ... }
There is an accepted answer but I would love if someone knows any other way of doing it without the use of spread operator. Thank you all
A quick way of doing it using the spread operator:
const condition = false;
const foo = {
bar: 'baz',
...(condition ? {
boz: 'bat'
} : {})
};
console.log(foo);
This works because the spread operator for object literals does nothing on objects without enumerable own properties.
To achieve expected result , use below option of adding propeter based on condition in separate line
https://codepen.io/nagasai/pen/ebQmrb?editors=1010
var add = false;
var obj = { foo: 'bar'};
if(add){
obj.bar = 'foo'
}
console.log(obj)
Option 2: Use undefined value for bar, if condition is false and use JSON.stringify and JSON.parse to remove undefined 'bar' property on condition -false
var add = false;
var obj = JSON.parse(JSON.stringify({ "foo": 'bar', "bar" : add? 'foo': undefined}));
console.log(obj);
codepen - https://codepen.io/nagasai/pen/zyMgxj?editors=1010

Cannot understand object with array as key [duplicate]

This question already has answers here:
Difference between ES6 object method assignment: a, 'a', and ['a']?
(2 answers)
Closed 6 years ago.
I've found some wild code on the web i don't understand:
return Object.assign({}, state, {
[action.subreddit]: posts(state[action.subreddit], action)
})
What is [action.subreddit] doing? I thought that object keys had to be strings but this appears to be an array?
I'm hoping to understand mechanically how this code works.
thank you!
That's not an array as key, it's the es6 way to use a variable (/ a computed property) as the key.
Consider this:
var a = "foo";
function getKey() {
return "myKey";
}
var obj = {
[a] : "bar",
[getKey()] : "baz"
};
console.log(obj.foo); // bar
console.log(obj.myKey) // baz
So [action.subreddit] just sets the key's name to whatever value action.subreddit is holding.

Shorthand for defining function in JavaScript object [duplicate]

This question already has answers here:
How does this object method definition work without the "function" keyword?
(2 answers)
Closed 6 years ago.
Accidentally I written a code like below,
var x = {hai:10,test(){ alert("I am alive")}};
x.test(); //alerting the value
It is working fine and I wonder how this code is working? since it was considered previously as an invalid grammar. And I know, In ECMAscript 6, there is a shorthand for assigning properties has been introduced.
Example:
var x = 5, y = {x}; // is as same as var x=5,y={x:x};
But I am not sure about the function definition. Can anyone explain about it with proof from documentation?
This is a Feature coming with ES2015. You can skip the function-keyword for method-definitions (not for plain functions).
So { doSth(){/*...*/ } } is simply a shorthand for { doSth: function(){/*...*/ } }
Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#Method_definitions
MDN
Starting with ECMAScript 2015 (ES6), a shorter syntax for method
definitions on objects initializers is introduced. It is a shorthand
for a function assigned to the method's name.
Syntax
var obj = {
property( parameters… ) {},
*generator( parameters… ) {},
// also with computed keys:
[property]( parameters… ) {},
*[generator]( parameters… ) {},
// compare ES5 getter/setter syntax:
get property() {},
set property(value) {}
};
You are now able to shorten this to:
var obj = {
foo() {},
bar() {}
};
MDN Links to ECMA
Enhanced Object Literals
Object literals are extended to support setting the prototype at
construction, shorthand for foo: foo assignments, defining methods,
making super calls, and computing property names with expressions.
Together, these also bring object literals and class declarations
closer together, and let object-based design benefit from some of the
same conveniences.
var obj = {
// __proto__
__proto__: theProtoObj,
// Shorthand for ‘handler: handler’
handler,
// Methods
toString() {
// Super calls
return "d " + super.toString();
},
// Computed (dynamic) property names
[ 'prop_' + (() => 42)() ]: 42
};
Reference : https://github.com/lukehoban/es6features#enhanced-object-literals

Why put an object key in square brackets (not destructuring)? [duplicate]

This question already has answers here:
What do square brackets around a property name in an object literal mean?
(2 answers)
Closed 7 years ago.
Look at the example here:
https://github.com/rackt/redux/blob/master/examples/real-world/actions/index.js
return {
[CALL_API]: {
types: [ USER_REQUEST, USER_SUCCESS, USER_FAILURE ],
endpoint: `users/${login}`,
schema: Schemas.USER
}
}
CALL_API is in square brackets so I assumed maybe it was an array and this was a destructuring thing.
But CALL_API is defined as
export const CALL_API = Symbol('Call API')
So it's not an array or anything. I've also seen the use of square braces with non-symbols. So what's the difference between
CALL_API: {}
and
[CALL_API]: {}
This is a computed property - it's the equivalent of:
let result = {}
result[CALL_API] = { ... };
return result;
Combining this with Symbol lets the library author create a protocol that will not collide with other protocols (e. g. if the protocol was a string "call" then it could collide with other libraries that use someObject.call for their (unrelated) protocols - as well as colliding with Function.prototype.call.)
What this is doing is taking the value of the express [CALL_API] and using it as the key, thus setting the key dynamically.
Example:
var x = "hello";
var y = {
[x]: "world"
};
console.log(y); // Object {hello: "world"}
After some testing, I recommend being very careful with this. The following is perfectly valid:
var x = {"will": "this work?"};
var y = {[x]: "let's see"};
console.log(y); // Object {[object Object]: "let's see"}
console.log(y['[object Object]']); // "let's see"

Categories

Resources