Reputation: 25312
I'm rendering a select element and I need to pass keyValues
to my component. To gather keyValues
, I map real object's values this way:
<Field keyValues={clients.map(client => {
key: client.Name,
value: client.Id
})} />
But as result I get an error Unexpected token, expected ;
. The error points to value
. What am I missing?
Upvotes: 0
Views: 4000
Reputation: 57964
This is because {}
is treated as a block, so your code is just identifiers with colons and values in the middle of nowhere... this is obviously invalid outside of an object literal, thus the error.1
The reason why is because arrow functions follow a certain syntax. Per the ECMAScript 2015 Specification:
14.2 Arrow Function Definitions
Syntax
ArrowFunction : ArrowParameters [no LineTerminator here] => ConciseBody ConciseBody : [lookahead ≠ { ] AssignmentExpression { FunctionBody }
As you can see, the arrow function allows for a concise body, which may be a block with a function body.
Because you are trying to return an object literal that happens to use curly braces, it is confused for a block and your property names and values are also confused for the function body.
To fix this, wrap the object literal in parentheses for an object to be returned:
<Field keyValues={clients.map(client => ({
key: client.Name,
value: client.Id
}))} />
The reason why this works is because only expressions can be in parentheses. Per the specification again:
12.2 Primary Expression
Syntax
CoverParenthesizedExpressionAndArrowParameterList : ( Expression ) ( ) ( ... BindingIdentifier ) ( Expression , ... BindingIdentifier )
Since a block is not an expression, it cannot be inside parentheses, so the {}
is assumed to be an object, thus an object is returned (an object is an expression).
1 In your example, key
is treated as a label. Since your line of code is an expression (client.Name
), it must be terminated by a semicolon. Since there is a comma instead, the error is thrown reporting a semicolon was expected but got comma.
Upvotes: 4