Why are the returned data the same? - javascript

let statList = {
title: {
x: "center"
},
xAxis: {
type: "category",
axisTick: {
alignWithLabel: true
}
},
yAxis: {
type: "value"
}
};
let statObj = {};
statObj.chatObj = Object.create(statList);
statObj.carObj = Object.create(statList);
statObj.saObj = Object.create(statList);
statObj.chatObj.xAxis.data = [1, 2, 3];
statObj.carObj.xAxis.data = [4, 5, 6];
statObj.saObj.xAxis.data = [7, 8, 9];
console.log(statObj)
Why are the returned statObj.XX.xAxis.data the same?
Why when I use console.log(JSON.stringify(statObj)), the result is {"chatObj":{},"carObj":{},"saObj":{}} ?

While setting statObj.chatObj.xAxis, xAxis is not found on chatObj, so xAxis is searched on the prototype chain (statList is the prototype of chatObj), where we could find it there. Until now we are done with the part statObj.chatObj.xAxis, next we move to create a .data key which will be create on statList.xAxis. Assignments with both statObj.carObj.xAxis.data and statObj.saObj.xAxis.data oberride what was set by statObj.chatObj.xAxis.data on statList.xAxis.data, that is why we have the result of statObj.XX.xAxis.data the last set value which is [7, 8, 9].

Usually I do solve this by using the following trick
statObj.chatObj = JSON.parse(JSON.stringify(statList));
I do not say this is a good practice, but in this way I am making sure the created object has it's own adress in the memory.
The problem with Object.assign() is that it is not working with nested properties, anyway the created object's are mutable.

Related

jQuery Loop though an object of arrays

I have a simple object with some simple arrays. I want to loop through each item in the object and check part of the array. For example, if a '0' or a '1' then do something.
var formvalidation = {
title: ['id1', 0],
categories: ['id2', 1],
price: ['id3', 1],
video: ['id4', 0],
fileTypes: ['id5', 0]
}
I've tried the following but I get the entire object in each loop.
jQuery(formvalidation).each(function(){
//Gives the entire object.
console.log();
});
It's a bit unclear what kind of processing you're trying to do with each property (see my comment requesting clarification).
The example below demonstrates how to loop through each property and extract the first and second value from the arrays you're storing. This example is meant to illustrate how to access each property and its values only - you'll obviously need to plug your logic in where appropriate.
var formvalidation = {
title: ['id1', 0],
categories: ['id2', 1],
price: ['id3', 1],
video: ['id4', 0],
fileTypes: ['id5', 0]
};
for (let prop in formvalidation) {
if (Object.prototype.hasOwnProperty.call(formvalidation, prop)) {
console.log(`Value of prop, ${prop}, is ${formvalidation[prop] [0]}:${formvalidation[prop][1]}`);
}
}
You could also use Object.keys, which is a bit cleaner:
var formvalidation = {
title: ['id1', 0],
categories: ['id2', 1],
price: ['id3', 1],
video: ['id4', 0],
fileTypes: ['id5', 0]
};
const keys = Object.keys(formvalidation)
for (const key of keys) {
console.log(formvalidation[key]);
}
Not to say that the previous answer here isn't right, but I thought Id go with what it led me to as the answer in this case.
jQuery.each(formvalidation, function(key, value){
if (value[1] == 0) {
e.preventDefault();
}
})

How do I use reduce() to mimic the capabilities of forEach()?

I'm trying to accomplish a task with reduce() that I know how to do with forEach(). Unfortunately I'm not sure how to structure the syntax and I can't find a good example.
Example 1) In this code I use forEach() to insert the word species into the first index of each array.
"use strict";
var creatureArray;
creatureArray = [
['zombie', 30, 1, 'bite', 0, 5],
['skeleton', 10, 2, 'sword', 1, 10],
['orc', 15, 4, 'club', 1, 7]
];
creatureArray.forEach(function(value, index, array) {
array[index].unshift('species');
});
console.log(creatureArray);
Example 2) In this code I try to accomplish something similar using .reduce(). However I know that I'm missing a piece of syntax. I can't figure out how to apply the updated array to the accumulator which is then returned as an object. Thanks so much for any help!
"use strict";
var creatureArray, creatureObject;
creatureArray = [
['zombie', 30, 1, 'bite', 0, 5],
['skeleton', 10, 2, 'sword', 1, 10],
['orc', 15, 4, 'club', 1, 7]
];
creatureObject = creatureArray.reduce(function(accumulator, currentValue, index, array) {
array[index].unshift('species');
//what goes here?
return accumulator;
}, {});
console.log(creatureObject);
Here is how you can do accomplish it.
"use strict";
var creatureArray, creatureObject;
creatureArray = [
['zombie', 30, 1, 'bite', 0, 5],
['skeleton', 10, 2, 'sword', 1, 10],
['orc', 15, 4, 'club', 1, 7]
];
creatureObject = creatureArray.reduce((accumulator, currentValue) => {
return [...accumulator, ['species', ...currentValue]];
}, []);
console.log(creatureObject);
The ... syntax above is called the Spread Operator.
When applied it expands the elements of the array into the new array created by the enclosing [ and ], placing each element from the old array as a top level element into the new array. This results in a flat array instead of a nested array. E.g [[1, 2]] -> [[1, 2]], but [...[1, 2]] -> [1, 2].
This is highly useful because it enables both simple concatenation as well as insertion of top level elements either before or after the expanded array.
Consider:
"use strict";
const names = ['Linus', 'Jane', 'David'];
const withJakeAppended = [...names, 'Jake'];
const withJakePrepended = ['Jake', ...names];
[names, withJakeAppended, withJakePrepended].forEach(xs => console.log(xs));
As you can see, when we spread an Array it is not modified, so the pleasant syntax also enables improved ergonomics for immutable, value oriented programming.
Even better, ... works with Sets and Maps as well. In fact, it works any Iterable object, including ones we can create ourselves.
I might add that using the fourth argument to either Array.prototype.forEach or Array.prototype.forEach is a poor practice that should be avoided.
Note if you need to do this in a browser without ES2015 support, you can write
"use strict";
var creatureArray, creatureObject;
creatureArray = [
['zombie', 30, 1, 'bite', 0, 5],
['skeleton', 10, 2, 'sword', 1, 10],
['orc', 15, 4, 'club', 1, 7]
];
creatureObject = creatureArray.reduce(function (accumulator, currentValue) {
return accumulator.concat([['species'].concat(currentValue)]);
}, []);
console.log(creatureObject);
map is more apropriate in this case:
var creatureArray = [ ['zombie' , 30, 1, 'bite' , 0, 5],
['skeleton', 10, 2, 'sword', 1, 10],
['orc' , 15, 4, 'club' , 1, 7] ]
var creatureObject = creatureArray.map(currentValue => ['species', ...currentValue] )
console.log( JSON.stringify( creatureObject ).replace(/],/g, '],\n ') )

How can show a someone data in JSON on javascript?

var example = {
"Equation" : [{
"name" : "My Equation",
"xMin" : [41901.0840,4,3,5,2],
"yMin" : [0.0000,4,5,7,8,9,3,1]
}
]
};
var e = JSON.parse(example);
alert(e.example.xMin);
/* What's the problem, can't show any data on array object, at least xMin is Array, how can show someone number on array. Thanks!. */
There is no need to parse since it's already a valid object. To get the property you need to get the Equation property and then it's the first element afterward get xmin property.
var example = {
"Equation": [{
"name": "My Equation",
"xMin": [41901.0840, 4, 3, 5, 2],
"yMin": [0.0000, 4, 5, 7, 8, 9, 3, 1]
}]
};
alert(example.Equation[0].xMin);

Are there limitations for nesting in Javascript? ("Error 21: Undefined is not an object" in Illustrator)

I'm using javascript with Adobe Illustrator CC 2015, and I'm trying to organize information about the artboards.
var myArt = {
types : {
type: "",
board : {
name : "",
refNum : 0,
chk : {}
}
}
};
//initialize
myArt.types = [0, 1, 2, 3, 4, 5, 6, 7, 8];
for (i=0; i<myArt.types.length; i++) {
myArt.types[i].board = [0, 1, 2, 3, 4, 5, 6, 7, 8];
for (j=0; j<myArt.types[0].board.length; j++) {
myArt.types[i].board[j].name = "";
}
};
I get Error 21: Undefined is not an object for the 2nd for loop.
As far as I can tell, what works for "types" should work for "board." The only difference I can see is that board is nested one level deeper. So I guess I'm wondering if there's some kind of limitation on nesting, or if there is some other problem that I'm not catching.
Your overriding myArt.types with an array of numbers. So in your second iteration when you are trying to do myArt.types[0].board.length you are actually calling 0.board.length,1.board.length, but 0.board is undefined. It looks like you are mixing up objects and arrays in javascript. Objects do not by default have a length property.
This is the data structure your loop is implying:
var myArt = {
types: [{
type: "",
board: [{name: "",refNum: 0,chk: {}}]
}]
};

Getting corresponding eNum key for the value passed

var StateValue = {
Unknown: 0,
AL: 1,
AK: 2,
AZ: 3,
AR: 4,
CA: 5,
CO: 6,
CT: 7,
DE: 8,
},
Now i need to get the enumValues.
function getKeyValue(stateVal) {
For example 'AK'
I need to get the corresponding value...
}
To answer the question in the title (in case someone comes for that), and not the one in the description, you can get the key by the value like this:
Object.keys(StateValue).find(
key => StateValue[key] === 2
)
this will return AK
It is simply:
var val = StateValue[stateVal];
You can access object properties with bracket notation.
I suggest to read MDC - Working with Objects.
var val = StateValue.AK would return 2, just like a regular ENUM

Categories

Resources