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

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.

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);

Can't get key from value within an object

I am trying to get the value associated with a key and create a new object, such as below. However when I assign the value of employeeCountryName to the object newCountryList, i get employeeCountryName returned and not "United Kingdom".
Any thoughts why this may be?
const countryList = {
"United Kingdom": "GBR"
};
const employeeCountryCode = "GBP"
const getKey = (obj, val) => Object.keys(obj).find(key => obj[key] === val);
const employeeCountryName = getKey(countryList, employeeCountryCode);
const newCountryList = {
employeeCountryName: employeeCountryCode
};
Keep in mind that when you define an object, it's keys aren't based on any other variables by default, they are just strings taken as keys. In order to tell javascript to take the value of a variable you have predefined instead of using it directly as a key, you need to add [] around them like this:
const variableName = 'keyToUse';
const object = { [variableName]: 1 } // { keyToUse: 1 }
You can use like that;
const newCountryList = {
[employeeCountryName]: employeeCountryCode
};
By the way, in your case find function couldn't find any key-value pair so it returns undefined. Because "United Kingdom" field has a GBR value and you're trying to find GBP

How to get the opposite property?

I have the following object with (always) 2 properties. It wil always have 2 properties. 3 properties won't be possible:
var people = {
'John': { ... },
'Peter': { ... }
}
And I have the variable var name = 'John'.
Is there a simple way to get the value of property 'Peter' when the value of name is 'John'?
Without hard-coding it with the names John en Peter. So the functionality must get the opposite property of the value in variable name
let name = 'John'; // or whatever
let names = Object.keys(people);
let otherName = names.find(n => n !== name);
people[otherName] // this gives you the value of the other name's property
Object.keys will give you an array of the property names.
filter lets you filter that array.
So:
const name = "John";
const people = {
'John': 1,
'Peter': 1
};
const [result] = Object.keys(people).filter(person => person !== name);
console.log({
result
});
I wrote a simple function, that does this. It takes a key, and an object. It returns the value of the element in the given object by the inverse key of the given key. This will only work if the object only has two keys.
var people = {
'John': { 'b':[3,4] },
'Peter': { 'a':[1,2] }
}
getInverseObjectElem = (key,object) => { // Define function 'getInverseObjectElem'
listOfObjectKeys = Object.keys(object) // Create an array of the object keys
inverseKey = listOfObjectKeys.filter(k => k != key)[0] // filter the list of keys, and get the first key that doesnt match the given key.
return object[inverseKey] // Return the value in the object, by the inverseKey
}
console.log(getInverseObjectElem('John',people))
You could try this:
for (let key in people){
if (key != name) return people[key];
}

Objects: Value always undefined

I am working on some keybinding functionality and came across something that is quite confusing to me.
I am doing some regex validation against the user defined keybinding pattern and would then like to assign the pattern as key and value to definedKeys:
const definedPattern = ['a', 'b']
let definedKeys = {}
const bindKeys = () => {
const charKey = (String(definedPattern[0]) + String(definedPattern[1])).match(/^[a-zA-Z]{2}$/)
if (charKey) {
definedKeys[charKey.input[0]] = definedKeys[charKey.input[1]]
}
console.log(definedKeys)
}
bindKeys()
Use definedKeys instead of definedCharKeys as it is not declared neither initailized
Assigning value directly to key instead of refrencing value from definedKeys because value is not still set and it will be always undefined.
definedKeys = {};
const encodeKey = (pKey) => {
charKey = (String(pKey[0]) + String(pKey[1])).match(/^[a-zA-Z]{2}$/);
if (charKey) {
// charKey.input = 'ab'
definedKeys[charKey.input[0]] = charKey.input[1];
}
}
encodeKey('ab');
console.log(definedKeys);
Isn't it because you don't put anything in definedKeys but instead you put it in definedCharKeys?
As per the code. You are not assigning anything in "definedKeys". You are assigning a value in "definedCharKeys" that's why you are getting undefined for the "definedKeys".
Please post full code where are you calling the function so that developers can provide you solution.

Destructuring fallback to prevent undefined error?

I have a list of array I do this:
const { id } = myArray.find(
(obj) => obj === true)
If the id is not present it will throw error. How to prevent error in the same time use destructuring? I want to keep the logic in one line.
The issue here is .find() returns undefined once there is no fulfillment for the condition:
The value of the first element in the array that satisfies the provided testing function. Otherwise, undefined is returned.
So probably you can use || operator to check if you have any value returned from .find() or you can replace with empty object {} instead on the right side of the operator.
Probably the option for one-liner is the following:
const myArray = [
{ id: 12 },
{ id: 13 },
{ id: 14 }
];
const { id } = myArray.find(e => e.id === 17) || {};
console.log(id);
So you can destructure id property even if it returned undefined in this way.
Also if you need you can add default value to your destructuring statement based on the documentation which states for Destructuring statement as follows:
A variable can be assigned a default, in the case that the value unpacked from the object is undefined.
const { id = 10 } = {};
console.log(id);
I hope this helps!

Categories

Resources