Confusion regarding Spread Operator in JS [duplicate] - javascript

This question already has answers here:
ECMAScript 6 arrow function that returns an object
(6 answers)
Closed 11 months ago.
So basically I have list of objects. I am iterating and have to change one property of the object. I have two scenarios, in one I have to change the property of a particular object.
setList(list.map((list_item)=>
list_item.id===id?{...list_item,doubleClick:true}:list_item
)
And there is another scenario where I have to change the property of every object in the list.
setList(list.map((list_item)=>{...list_item,doubleClick:false}))
The first case is working fine but the second case is throwing error >Parsing error: Unexpected token (34:35)
To me they don't look that different except first one has ternary operator? Is that what's making a difference?
How to fix the second case?
Edit: So I think spread operator works with an expression or declaration.
setList(list.map((list_item)=>list_item={...list_item,doubleClick:false}))
This works.
Is there any better or correct way to do it?

In your second case, you need to return the new object.
setList(
list.map((list_item) => {
return { ...list_item, doubleClick: false };
})
);
Or a shorter way is to wrap the new object inside ()
setList(list.map((list_item) => ({ ...list_item, doubleClick: false })));
Read more about the syntax here
Edit:
The syntax in the third case is fine but the logic isn't correct. You want to return the new object, not reassign elements in .map()

Related

how to return array of objects from .map [duplicate]

This question already has answers here:
ECMAScript 6 arrow function that returns an object
(6 answers)
Closed 4 years ago.
in the below code, activeProgs is an array contains program objects. i am using .map because i would like to have an array containing the name of the
program and a token value. this token value is an integer and it could be incremented by one for each program as shown below in the code.
my question is, if i want to have the same array that contains the program name and the token but as an object. in other words, i want the .map()
to return an array but that array contains objects with two attributes "progName" and "token". can i do the following?
activeProgs.map((prog)=> {progName: prog.getHeader().getName(), token: (++i)} )
please let me know how to do it correctly
code:
activeProgs.map((prog)=> prog.getHeader().getName() + '->' + (++i))
like so:
activeProgs.map((prog) => ({progName: prog.getHeader().getName(), token: (++i)}) );
or like so:
activeProgs.map((prog) => {
return {progName: prog.getHeader().getName(), token: (++i)}
})
In the first example, adding brackets around the {} forces it to be parsed as an expression containing an object literal. In your code, it is interpreted as part of the function declaration, making the next bit a syntax error.
The second one makes that more explicit
You weren't far off with the example you suggested, you just needed to wrap the object in brackets so the compiler understands you are returning an object and not declaring a function body
activeProgs.map(prog => ({
progName: prog.getHeader().getName(),
token: (++i)
}))

this value doesn't reference current scope instead refrences parent scope in ES6 arrow style function [duplicate]

This question already has answers here:
Methods in ES6 objects: using arrow functions
(6 answers)
Closed 5 years ago.
I am little new to ES6, but not with node js, but this looks little weird because when I started using arrow style function instead of function() style, I was in assumption that both are exactly same but the syntax is different. But today came to know about this case.
When I define a function like this.
exports.intent = {
greetings: {
matcher: ["hi", "hello"],
reply: function(){
console.log(this); // it prints {greetings: {..}} expected
return this.matcher[0]; // returns "hi" which is expected.
}
}
}
But when I defined same function in arrow style, it throws error as this here now references the whole object instead of current object.
exports.intent = {
greetings: {
matcher: ["hi", "hello"],
reply: () => {
console.log(this); // it prints whole object {intent: {....}}
return this.matcher[0]; // fail here.
}
}
}
I came to know that there are some changes in this refrencing between these 2 types of declaration. https://stackoverflow.com/a/40498293/2754029
Is there are any way so that I can refrence this to current object only?
No. You will not be able to override this inside an arrow function body. Even if you try to bind it, it doesn't work. This one is an interesting article I came across recently.

Javascript syntax []() and ()() [duplicate]

This question already has answers here:
How does this object method definition work without the "function" keyword?
(2 answers)
Closed 6 years ago.
I'm having trouble understanding these javascript syntaxes. In the block of code below, on the second line. The square bracket is quickly followed by a round bracket or parentheses which I suspected is used to get arguments. I do not understand how this two is being chained to form an expression and what it means.
export const recipeCount = createReducer(0, {
[types.ADD_RECIPE](state, action){
return state + 1;
}
});
Also on this line, the connect method takes in two arguments, (state) => {return {}} and mapDispatchToProps . Then it is quickly follwed by () with an argument. At first, i though it was some of object casting in java but that doesn't make sense.
export default connect((state) => {return {}}, mapDispatchToProps)(AppContainer);
The code executes fine and produces expected result. I just don't understand what is going on. Pls Help, would be glad to get answersre accompanied with links to pages i can read for better understanding. Thanks.
Answers are in the comment to the question. Had to copy them out again, so i can mark the question as answered and close it.
"Not sure what's going on with the first one. For the second one, connect() is a function that returns a function so the second () is to immediately call that returned function." – Ouroborus
"The first one is a dynamic object literal property that is also an object method. I find this not readable at all. I would re-write that one. – Davin Tryon"
and also a link to Computed property names to make it clearer from – Denys Séguret
Thanks Guys.

Any way in JavaScript to deep-check an object for a truthy value? [duplicate]

This question already has answers here:
Null-safe property access (and conditional assignment) in ES6/2015
(11 answers)
Closed 6 years ago.
I believe there's a mechanism for this in CoffeeScript (the ? token), but I'm wondering if there's a better way to do this kind of check in ES6:
if (item && item.integrations && item.integrations.slackData) ...
(besides writing a helper function, which is the immediately obvious solution)
EDIT: The goal here is to make the code is simple and terse as possible.
Example object:
item = { integrations: { slackData: { url: '...' } } };
EDIT 2: Thanks for pointing out the duplicates. I couldn't figure out what terms to search for. I'm probably going to go with using lodash's _.get() function.
You can use Array.prototype.every()
var check = [item, item.integrations, item.integrations.slackData]
.every(function(element) { return element });
Edit, Updated
As noted at comments by #FelixKling, the pattern at above using .every() will fail if item.integrations is undefined.
Given the example object at Question you can use JSON.stringify(), String.prototype.match() with RegExp /"integrations":|"slackData":|"ur‌​l":/g/, then check that .length of resulting array, if any, is equal to the number of properties expected; in the present case 3.
A javascript object which is passed to JSON.stringify() should have properties with the following pattern:
" followed by property followed by " followed by :. Depending on the source object, the RegExp can be further adjusted to meet the specific properties and values of that object.
JSON.stringify(item).match(/"integrations":|"slackData":|"ur‌​l":/g).length === 3
Note that JSON.stringify() has a replacer option which can be used to match properties of the object. The replacer function option is recursive. See also
remove object from nested array
Nested object and array destructuring
Convert javascript object to array of individual objects
How do I filter Object and get a new Object?
but I'm wondering if there's a better way to do this kind of check in
ES6:
The present Answer does not attempt to indicate that using JSON.stringify() and RegExp to match or filter a javascript object is "better"; but only that the approach can meet the described requirement at the present Question.

Dynamically call function in javascript [duplicate]

This question already has answers here:
Calling function inside object using bracket notation
(2 answers)
Closed 6 years ago.
I rather have a seemingly trivial issue, but am not able to figure out an efficient approach.
I have a list of about 50 functions to be called such as :
globalClient.funcA(...)
globalClient.funcB(...)
globalClient.funcC(...)
My code should ideally dynamically create the name of the function (funcA / funcB/ funcC and then proceed to actually call that function. My approach below does not work (please note that these aren't exactly the actual names of the functions. I'm only giving these arbitrary names for simplicity of understanding):
var functionName = 'func'.concat('A');
globalClient.functionName
The second line is where it errors out. Now JS thinks that functionName itself is the name of the function. What I want it to do is resolve functionName to funcA and then call globalClient.funcA(...) instead.
I've thought about implementing a switch / case for this but I'm sure there is a far simpler appraoch. Any ideas?
You could use the bracket notation as property accessor.
globalClient[functionName]()
You can use the [ ] operator for accessing the properties.
var globalClient = {
funcA: function(){
console.log('funcA is called');
}
}
var functionName = 'func'.concat('A');
globalClient[functionName]();

Categories

Resources