I have the following line with destructuring syntax;
const [
{data: dataResponse},
{data: stateDistrictWiseResponse},
{data: statesDailyResponse},
{data: stateTestResponse},
{data: sourcesResponse},
{data: zonesResponse},
] = someArr;
someArr is an array of objects (actually result of Promise.all([url1, url2,...], where each url returns a json object)
How is the above destructuring syntax evaluated?
The values extracted via destructuring syntax closely parallels the syntax of an object literal. For example, if someArr is defined as (or contains):
const someArr = [
{data: 'dataResponse'},
{data: 'stateDistrictWiseResponse'},
];
then the syntax
const [
{data: dataResponse},
{data: stateDistrictWiseResponse},
] = someArr;
will put the 'dataResponse' string into the dataResponse variable, and the 'stateDistrictWiseResponse' string into the stateDistrictWiseResponse variable.
The colon after the property indicates that the property is being extracted into a variable whose name is on the right of the colon. (If there is no colon when destructuring, the value is put into a new variable name which is the same as the property name, eg const { data } = someObj creates a variable named data which holds the value at someObj.data).
Your original code is quite hard to read though. I'd highly recommend mapping to create a new array of only the data properties first, then destructuring:
const dataArr = someArr.map(({ data }) => data);
const [
dataResponse,
stateDistrictWiseResponse,
statesDailyResponse,
stateTestResponse,
sourcesResponse,
zonesResponse,
] = dataArr;
Related
I want to set multiple objects as multiple values of another object. So for example
let dataObj ={}
const personData = {name:"sai",age:"20"}
const ids = {id1:"1231455",id2:"425325232"}
dataObj.personData = personData;
dataObj.ids = ids
console.log(dataObj);
'personData' is a object and 'ids' is a object.Im setting these 2 objects as 2 values for 'dataObj'.
I was wondering is there a shorter way to achieve this like:
let dataObj ={}
const personData = {name:"sai",age:"20"}
const ids = {id1:"1231455",id2:"425325232"}
dataObj = personData;
dataObj = ids
console.log(dataObj);
The problem with the alternative I suggested is that it wont set 'key' of 'dataObj' object.It will just set the values of 'personData' and 'ids' to the value of dataObj.Is there any way I can achieve this ? Specifying multiple objects as values to another object with keys?
You can achieve this using the spread syntax:
let dataObj = {};
const personData = {name:"sai",age:"20"}
const ids = {id1:"1231455",id2:"425325232"}
dataObj = { ...dataObj, personData, ids };
console.log(dataObj);
/*
output :
value of dataObj:
{
personData: {
name: "sai",
age" "20"
},
ids: {
id1: "1231455",
id2: "425325232"
}
}
*/
I'll try and explain spread using the above example. First we start with an empty object dataObj: {}. We want to add new properties to that object: personData with the personData object as value and ids with the ids object as value.
ES2015 added a shorthand syntax for setting property definitions in objects. That's what been used here:
dataObj = { personData, ids };
This is simply a cleaner way of writing
dataObj = {
personData: personData,
ids: ids
};
More info on this can be found on MDN.
Because you want to initialise your object before, we can't simply overwrite the object, but we need to add the new properties to the existing object. This can be done using the spread syntax.
const oldObject = { key: 'value', anotherKey: 'another value' };
let newObject = { ...oldObject };
// newObject value: { key: 'value', anotherKey: 'another value' };
The oldObject was 'spreaded' in newObject. Resulting it in having the same key-value pairs as oldObject.
In your code example we assign a new object to dataObj. In that new object we spread all properties which are in the current dataObj: { ...dataObj and then add the new properties: , personData, ids }.
I hope this explanation is clear, feel free to ask for more info. The spread syntax is very powerful and can be used for a lot of things. So be sure to read up on that.
You can merge two objects as below. You can use '...' spread object. the spread object works for objects as well. Clone an object as shown in below code. for more information please visit https://flaviocopes.com/javascript-spread-operator/
let dataObj = {}
const personData = { name: "sai", age: "20" }
const ids = { id1: "1231455", id2: "425325232" }
dataObj = { ...dataObj, personData, ids }
console.log(dataObj);
Using Javascript, how do I create an array within an object that's within an object, so that my value is stored at: main[1].type[1][0]
I have tried and my code which does not work is as follows:
let main = []
main[1] = {type: {1:['Value1', 'Value2']}, {2:['Value3', 'Value4']}};
console.log(main[1].type[0][1]);
I expect main[1].type[1][0] to be 'Value1' but it is undefined
You're not getting undefined. You have a syntax error. A comma should either be separating array values, or separating object entries. You have a comma here, in an object, so it is expected to have a key after it, not a {
main[1] = {type: {1:['Value1', 'Value2']}, {2:['Value3', 'Value4']}};
|
|
Remove the } and { around this comma
Remove the } and { around the comma so that {1:['Value1', 'Value2'], 2:['Value3', 'Value4']} becomes a single object with two keys:
const main = [];
main[1] = {type: {1:['Value1', 'Value2'], 2:['Value3', 'Value4']}};
console.log( main[1].type[1][0] );
First your declaration is wrong and will not works.
{type: {}, {}} isn't a valid JSON and you must wrap it into [] to create array of object {type: [{}, {}]}.
Also by adding a level you will have to ask for: main[1].type[0][1][0] to get the complet path to Value1
let main = []
main[1] = {type: [{1:['Value1', 'Value2']}, {2:['Value3', 'Value4']}]};
console.log(main[1].type[0][1][0])
Your problem is you can not create an object with a numbered object inside it you have to use the array notation var variableName = [/*variable values here separated by commas*/]
This will fix your problem:
let main = []
main[1] = {
type: [
['Value1', 'Value2'],
['Value3', 'Value4']
]
};
console.log(main[1].type[0][1]);
Breaking down your issue, an object must be "zero or more pairs of property names and associated values of an object." The second value in the question's code does not have a key, causing an uncaught SyntaxError.
Here's an object literal that returns your desired result:
const main = {
1: {
type: { 1: ['Value1', 'Value2'] },
otherType: { 2: ['Value3', 'Value4'] },
},
};
main[1].type[1][0]
=> "Value1"
Object initializer docs
Another option could be to use sparse arrays :
let main = [, { type: [, ['Value1', 'Value2'], ['Value3', 'Value4'] ] } ];
console.log(main[1].type[1][0]);
So I have this code in vue:
export default {
name: 'Test',
data() {
return {
test1: ['1', '2', '3'],
test2: [{
name: 'Hello'
}, {
name: 'Number two'
}, {
name: 'What ever'
}],
};
},
created() {
const first = [...this.test1];
first.forEach((elm, index) => first[index] = 'New');
console.log('first: ', first);
console.log('test1 in data', this.test1);
const second = [...this.test2];
second.forEach(elm => elm.name = 'New');
console.log('second: ', second);
console.log('test2 in data', this.test2);
},
}
After setting the value of each item of the array 'first' (that should be a copy without reference to the data 'test1' array) each item is equal to 'new'. The value of this.test1 doesn't change.
I did the same with test2. Copied and changed the value of each item to 'New'. But now the value of the data array 'test2' also has 'New' in every item.
I have no clue why this is like that. Any ideas?
Spread syntax creates a shallow copy. If your array has primitive types like numbers or strings, it won't update the original array. That's the case with test1. In the second case, only a new array is created. If you push or pop from the array, original array won't be updated. But, the objects are still pointing to their same place in memory. Updating them will update original array's objects as well.
You can use the spread syntax on the individual object to create a copy of the objects:
const second = this.test2.map(o => ({...o}))
You can also use JSON.parse and JSON.stringify. But, if the objects have any function properties, they'll be removed.
const second = JSON.parse(JSON.stringify(this.test2))
The reason it is like that is because you are having an array of Vue data values. So even though you are cloning the Array, you are also copying over each values 'getters' and 'setters' which have a reference to the original array. In order to remove the getters and setters you should do what d-h-e has suggested.
You could also do this.
const second = this.test2.map(() => { name: 'New' } );
console.log('second: ', second);
console.log('test2 in data', this.test2);
Try it with:
const second = JSON.parse(JSON.stringify(this.test2));
The copy method with spreadoperator or Array.from works only with simple arrays.
For deep copy use the method with JSON.parse and JSON.stringify.
Basically I have got an object, which will be multi-dimensional and the properties could be named anything and it could have many dimensions.
At some point I will need to append/splice a property within this object, from code which won't know it's position.
So, an example object:
let obj = {
response: {
locations: {
data: [
0: Object,
1: Object,
2: Object,
]
}
},
endpoint: null
}
I need to splice out data.locations.data[1], the only information I have is the below array and the index. Obviously I will know the first property will be response.
['locations','data']
index: 1
Edit:
My mistake, the data property has an array value not an object!
You can use Array#reduce() and pass in obj.response as the start value to get at the nested parent which based on the array shown would be obj.response.locations.data.
Then splice() the indexed item in that parent or do whatever other modifications are needed
const arr = ['locations','data'],
index= 1,
obj = {
response: {
locations: {
data: [{id:1},{id:2}, {id:3}]
}
},
endpoint: null
}
const targetArr = arr.reduce((a,c)=> (a[c]), obj.response);
targetArr.splice(index,1);
console.log(obj)
Is it good practice to use a object literal as a hash table? i.e use a property name as the key to get a particular mapped value back.
For example:
var colorArray = [
{ code: "#4286f4", name: "Blue" },
{ code: "#fc4d02", name: "Red" }
]
var hashTable = {}
colorArray.forEach(color => {
hashTable[color.code] = color.name
})
Is this an acceptable use for object literals, or is there a pattern out there that will better handle a hash map in JavaScript?
Before ES6 using a literal object was the only way to have a hashmap in JS. Since ES6, you can also use Map:
const colorArray = [{code: "#4286f4" , name: "Blue"}, {code: "#fc4d02", name: "Red"}];
const map = new Map(colorArray.map(({ code, name }) => [code, name]));
console.log(map); // look at the browser's console
console.log(map.get("#4286f4"));