Name of this switch operator syntax - javascript

I am constantly finding this sort of switch statement in a codebase and not being able to find documentation about it anywhere. Does anyone know the name of this syntax?
import React from 'react'
enum Options {
FirstOption = 'first',
SecondOption = 'second'
}
export default function DisplayIcon({selectedOption: string}) {
const clickFirst = () => {
// do something
}
const clickSecond = () => {
// do something
}
return (
<Wrapper>
{
{
[Options.FirstOption]: (
<ClickableIcon onClick={ clickFirst }>
<Icon type={ IconType.Frist } />
</ClickableIcon>
),
[Options.SecondOption]: (
<ClickableIcon onClick={ clickSecond }>
<Icon type={ IconType.Second } />
</ClickableIcon>
),
}[selectedOption]
}
</Wrapper>
)
}

It's not a switch statement at all, though you're right it's being used to select a value. It's an object literal with computed property names. So it's building an object, then picking out the property matching selectedOption from that object, all in the same expression.
Here's a simpler example of the object literal part with computed property names:
const name1 = "a";
const name2 = "b";
const obj = {
[name1]: "value for a",
[name2]: "value for b",
};
console.log(obj);
And here's an example of what that code is doing with building the object and then immediately grabbing one of its properties:
const name1 = "a";
const name2 = "b";
const pickOne = Math.random() < 0.5 ? name1 : name2;
const pickedValue = {
[name1]: "value for a",
[name2]: "value for b",
}[pickOne];
console.log(`Picked "${pickOne}": "${pickedValue}"`);
FWIW, I wouldn't do it that way. I'd either define the object once and reuse it, or use a switch or if/else if or similar in the code prior to the return.

This isn't specific to JSX, and isn't really a particular piece of syntax, but a combination of multiple. Let's simplify it a bit:
let result = {
[Options.FirstOption]: 'hello',
[Options.SecondOption]: 'goodbye',
}[selectedOption];
This will select either 'hello' or 'goodbye'. It does so by first creating an object, and then looking up a property on it. We could add an intermediate variable like this:
let options = {
[Options.FirstOption]: 'hello',
[Options.SecondOption]: 'goodbye',
};
let result=options[selectedOption];
The [...]: syntax is just to allow the keys themselves to be defined based on some other variable, rather than a literal string. We could instead add properties one at a time like this:
let options = {};
options[Options.FirstOption] = 'hello';
options[Options.SecondOption] = 'goodbye';
let result=options[selectedOption];
The result, as you already worked out, is equivalent to this:
let result;
if ( selectedOption === Options.FirstOption ) {
result = 'hello';
}
elseif ( selectedOption === Options.SecondOption ) {
result = 'goodbye';
}

Related

how to deal with Computed and Destructuring assignment in Vue3?

const index = ref('child1')
const children = {
child1:{ name:'foo' },
child2:{ name:'bar' },
}
// case 1. I want to destructur and get name variable when index variable is changed to 'child2'. Because computed is not used here, it is not responsive, name variable still is 'foo'
const {name} = children[index.value]
// case 2. After using computed
const child = computed(() => children[index.value])
// Because I used Computed, I got the child object, but I can't deconstruct it
// so I need to use child.name in the template, and i dont want that.
// My puzzle is how to use the name field directly, as in case 1, and responsive as in case 2
// maybe Reactive with toRefs?
I got a playground to explain my confusion
I expect to use the name field directly, as in case 1, and responsive as in case 2
a) deconstruct with toRef or toRefs:
const child = computed(() => children[index.value])
const { name } = toRefs(child)
const name1 = toRef(child, 'name')
b) get name directly
const childName = computed(() => children[index.value].name)
c) use Reactivity Transform (experimental)
const child = computed(() => children[index.value])
const { name } = $( child ) // name is string
You could define the computed to be the name directly:
const name = computed(() => children[index.value].name);

Get JSON value by using variables on the 2nd level of depth

I have a .json file like this:
{
"width": 700,
"height": 1382,
"dataID": {
"id1": "54321",
"id2": "12345"
}
}
I need to get value of id1 or id2 keys dynamically (using a variable). I use Cypress function cy.read() and by using definite strings it works good:
cy.readFile(pathToConfigFile).then(($file) => {
const id1value = $file.dataID.id1;
});
But how to wrap this expression into variable containing id1?
There is a similar question : Dynamically access object property using variable
However the solution proposed there refers only to the first level of depth. With square brackets I can get the following values:
cy.readFile(pathToConfigFile).then(($file) => {
const customVariable = "dataID";
const id1value = $file[customVariable];
});
But in case of it returns id1value = undefined:
cy.readFile(pathToConfigFile).then(($file) => {
const customVariable = "dataID";
const id1 = "id1";
const id1value = $file[customVariable][id1];
});
You will need to check the value of the variable after the first check so you know whether you can read the second-level value.
cy.readFile(pathToConfigFile).then(($file) => {
const customVariable = "dataID";
const id1 = "id1";
const idValues = $file[customVariable];
return idValues ? idValues[id1] : undefined;
});
Instead of undefined you can return some default value if you prefer.
There are also packages which can be used to do this automatically for you, such as lodash's _.get() method.

How to conditionally create object property in one line? [duplicate]

This question already has answers here:
In JavaScript, how to conditionally add a member to an object?
(29 answers)
Conditionally set an object property
(7 answers)
How to conditionally add properties to a javascript object literal
(8 answers)
Closed 8 months ago.
I want to create a property on an object conditionally.
The idea is to ensure the property doesn't exist (so not just null) if it has no value.
What I'm doing right now:
// comes from users
req.query = {
foo: true
}
// my object which will contains allowed properties IF EXISTS
const where = {}
if (req.query.foo) {
where.foo = req.query.foo
}
if (req.query.bar) {
where.bar = req.query.bar
}
console.log(where)
It's really boring to repeat this for every different property...
Is there a way to do it in one line?
EDIT:
I don't want to get all properties from req.query
Create object property obj.foo if value exists (or any other condition)
&& operator returns second element if the first boolean condition is fulfilled
es6 spread operator ... does what it does)
const value = 'bar'
const empty = undefined
const obj = {
...value && { foo: value }, // read ...(value && { foo: value }) parenthesis are not necessary
...empty && { empty },
...(100 > 0) && { condition: 'true' },
...(100 < 0) && { condition: 'false' },
}
console.log(obj)
You could do:
const merged = {...where, ...req.query};
Try this:
const elements = ["foo", "bar"];
elements.forEach(el => {
if (req.query[el]) {
where[el] = req.query[el];
}
});
You can simply write it in one line like this :
let where = {};
if (req.query.foo) where = {...where, foo : req.query.foo };
if (req.query.bar) where = {...where, bar : req.query.bar };
I hope that it helps.
If you want a simple one liner (maybe less readable), you can do:
Object.keys(req.query).forEach(key => req.query[key] && (where[key] = req.query[key]));
If you're okay adding a pluck function, you could do it like this:
const req = { query: { baz: '1', foo: '3' } };
const where = {};
const pluck = (keys, obj) =>
keys.reduce((a, k) => typeof obj[k] === 'undefined' ? a : Object.assign(a, { [k]: obj[k] }), {});
const add_foo_bar = (where, query) =>
Object.assign({}, where, pluck(['foo', 'bar'], query));
const res = add_foo_bar(where, req.query);
console.log(res);

Javascript array find check for undeifned

I am using javascript array.find on my list of object arrays. I want to get another property of that object only when compared to that
property is available.
When compared to t, I get value as 'Value1'
When compared to t1, I get undefined. I want to check for 'undefined' and get the value only when available.
const t = 'abc';
const t1= 'xyz';
temp = [ {key: "abc", value: "Value1}]
temp.find( check => check.key === t ).value);
Depending on how you intend to use the value, you will likely find you need some type of value as a result of your search. This will allow you to substitute something or nothing as needed.
const t = 'abc';
const t1= 'xyz';
temp = [ {key: "abc", value: "Value1"}]
const result = temp.find( check => check.key === t1 ) || {value:'Not Found!'};
console.log(result.value);
Firstly, you were missing a closing quote. Secondly, use some and find:
const t = 'abc';
const t1= 'xyz';
const temp = [{key: "abc", value: "Value1"}];
if (temp.some(({ key }) => key == t)) console.log(temp.find(({ key }) => key == t).value);
If you want it to throw an error, return undefined, return a default or something else, you can check for undefined like so:
x = list.find(logic)
if(x){
//carry on as normal
else{
//handle it not being found
}

How do these 2 notations differ in meaning in React.js?

Came across these 2 notations recently. While both appear to be doing similar things, one of them uses an assignment operator while another one appears to be an object. Are they doing anything different?
const { value = "" } = this.props;
and
let { value: newValue } = newProps;
Both of these are destructing an object. When you use = you are setting a default value if the value is undefined/null. With : you are aliasing the variable. You can even combine them:
const { value : value2 = 'Hello' } = this.props;
console.log(this.props.value); // World
console.log(value2); // World (since value2 IS this.props.value aliased)
// ...or if this.props.value isn't defined
console.log(value2); // Hello
It has nothing to do with React library actually. They are ES6 destructuring assignments.
The first example will create a constant variable called value and will assign whatever is this.props.value (Object, Array, Number). If this.props.value is undefined though it will use default value = "" - empty string.
const { value = "" } = this.props;
In a second example, newValue variable will be created and it will equal to newProps.value (even if it is undefined).
let { value: newValue } = newProps;

Categories

Resources