Changing the variables of a class in OOP in javascript - javascript

I have defined a function called Node which stores the properties of nodes in a graph data structure. The function is something like this:
function Node(){
...
this.outEdges = [];
this.inEdges = [];
...
}
where the inEdges and outEdges store elements of type Edge which is another function I have defined. During the program these arrays are filled with elements.
At some point in my code I need to reset these two arrays so I write:
nodes[i].outEdges.length = 0;
nodes[i].inEdges.length = 0;
where nodes is an array of elements of type Node and I am accessing an element in a for loop.
The problem is, after setting outEdges and inEdges to 0, I expected them to be [] in the nodes[i] property list. However, when I output nodes[i] into console, the outEdges and inEdges still have the elements in them. The stranger thing is that when I output nodes[i].outEdges to console, it prints [] , which is correct, but clicking on [ ] again opens the list of the elements! I can't really figure out why the nodes[i] variables don't change?

That happens (probably) because the browser prints out the empty array but by the time you check it, it has content again. So when you click to expand the browser shows the actual content.
As you can see the values [1,3,7] were added after the command console.log(o) but they are shown on the screen (even though the length shown is 0).

You're not supposed to set the length field. Just re-initialize them:
nodes[i].outEdges = [];
nodes[i].inEdges = [];
Edit: My bad, setting the length should work. It does work for me on Chrome at least. However, I still think it's safer and better style to re-init.

Just create a new object with the same name
nodes[i].outEdges = new Array();

Related

Why does this array have object key value pairs?

I didn't even know that this was possible, what is this? I tried running this on chrome and firefox, and got the same result:
I'm sending a 100 item array from the server, but when it gets to the client, this happens.
I tried accessing the item at index 100, and got undefined as response.
I also tried slicing it to the first 100 items, but the rest of the key pairs remain there.
I can't try to access the values by key because they are random every time. If that's of any value.
Since an array is also an object, you can add arbitrary properties to it. Run this code then look in your browser console (not the console inside this post).
const array = ['11034.61000000', '0.30200000'];
array['10987'] = 0.009101;
array['11024.05'] = 0.001998;
array['11026.96'] = 0.001;
array['11026.59'] = 1.5;
console.log(array);
console.log(Object.keys(array));
Object.keys(array) will show you every property of the array, even the random ones.

Parsing a JSON object of arrays gives different results in IE9

Intro
I am working on creating a HighCharts graph from a DataTable table.
What I do is iterate over the the rows and columns of the table, convert the strings (we use different thousand separators from the US) to numbers and save them into an object called item. the object has two values item["name"] which is the name of the series and item["data"] which is the data for the series. I then use the .push method to add these objects to an array to send to a Highcharts options object to create the plot. In the case below, I only have three series, but the problem always occurs. The LineOptions is an options-object for the HighCharts Graph.
Code
function plotLineOrBar(type){
var jsonData = [];
var xaxis = $('#masters_table table').find('thead th:not(:first-child)').map(function(){
return $(this).html();
}).get();
$('#masters_table table tbody tr').each(function(){
item = {};
item["name"] = $(this).find('td:first-child').html();
item["data"] = $(this).find('td:not(:first-child)').map(function(){
return parseInt($(this).html().replace(/\./g, "").replace('',0),10);
}).get();
jsonData.push(item);
});
console.log(jsonData[0]["name"]); // send the 0th name to console
console.log(jsonData[1]["name"]); // send the 1st name to console
console.log(jsonData[2]["name"]); // send the 2nd name to console
LineOptions.series = (jsonData);
LineOptions.xAxis.categories = xaxis;
LineOptions.chart.type=type;
var chart = new Highcharts.Chart(LineOptions);
}
Problem
(The name of the series should be 2320,2321,2336)
In Chrome, the resulting console.log is:
2320
2321
2336
and the corresponding data to each series prints out correctly and everything works flawlessly.
In IE9, the resulting console.log is:
LOG: 2336
LOG: 2336
LOG: 2336
i.e., only the last series gets printed into the array. The result is three series with perfectly overlapping curves, since they have the same data.
I have searched and searched for answers, wrapped by brain around but I can still not figure out what I am doing wrong. I assume though, that my error is a simple one (I hope).
As previously wrote in the comment (for future reference), just define the item variable inside of the loop function, instead of using a "global" one (var item = {} instead of item = {}). This is because in IE9 it seems to be passed by reference, and thus you're pushing the very same object, updated three times (changing its values from iteration to iteration).
P.S.
by the way it seems that the other browser you're using, it is creating a new variable every time you use .push and I'm not sure that's the "standard" behavior. One point to IE9!

Change the div's in another html page

still learning some javascript here, got done other things but now the final and most important part of it.
I have two html pages - one of which uses javascript to dynamically add text-fields (and to remove them of course) (genmain.html) and the other one where the text field input should go(table.html).
So i have already created a function to retrieve the array of values.
function getElementArray(divName){
var names = document.getElementsByName("namefield");
}
The variable names is an array and it has all the values from fields.
The problem is I would like to set these values from array to the values of another div on the page. After some searching i understood that it could be done with 'id'-s but i'm not that sure and don't completely understand how.
Let's say i have a lot of div's on another page (table.html) but some of them have id="MAIN". I would like to change the value inside of the div
For example
<div id="MAIN">THIS PART I WANT TO CHANGE</div>
Javascript is not part of my school system and i've done CodeAcademy tutorials and that's the most i've got about this, I hope you guys can help with my issue.
The variable names is an array and it has all the values from fields.
function getElementArray(divName){
var names = document.getElementsByName("namefield");
}
Nope, you've only got reference to the elements here. You've not got the value yet.
You can get the values by iterating through the names Nodelist array and use names[i].value
The problem is I would like to set these values from array to the
values of another div on the page
If it's going to be in same page, then use innerHTML or textContent property of the DOM to assign the value.
document.getElementById("MAIN").textContent= names[1].value;
Just for demo purpose am using names[1] here so it will load the second input value.
Let's say i have a lot of div's on another page (table.html) but some
of them have id="MAIN". I would like to change the value inside of the
div
Once you move to another page, the javascript state will be lost. So you wont have access to names inside that page.
Either you must store the values into localStorage and retrieve in next page.
Else add the values to query string of your URL and retrive it there.
Edit: Update based on comments
Let us assume you have var names = document.getElementsByName("namefield"); so to store the values inside localStorage.
var myValues = [],
names = document.getElementsByName("namefield");
for(var i = 0; i < names.length; i++) {
myValues.push(names[i].value);
}
localStorage.myValues = JSON.stringify(myValues);
Now if your next page, Iinside window.onload event:
window.onload = function() {
var myValues = localStorage.getItem("myValues") ? JSON.parse(localStorage.getItem("myValues")) : [],
divElements = document.querySelectorAll("#MAIN");
for(var i =0; i < myValues.length; i++) {
divElements[i].textContent = myValues[i];
}
}
If you want to set or change the contents of an element, you can use the innerHTML property.
So in your case, document.getElementById("MAIN").innerHTML = "Whatever you want";
For the record, names in your example technically isn't an array, but a NodeList. See https://developer.mozilla.org/en/docs/Web/API/NodeList#Why_is_NodeList_not_an_Array.3F.

Incorporating localStorage in a more complicated scenario (save multiple arrays)

I'm trying to implement local storage into my program.
Initially, the program was simple and had only 1 array to save. That array served as the container and the container then fed to #1 - the display output and to #2 - the console output...
old simpler program
pseudo-code to make the red box go away...
The above link eventually worked - as you can see on line 54 of the JS, as soon as a new entry is entered into the input box, the updated container was then saved to localStorage. And then upon returning to the site, per line 11 - if upon the initial loading of the program the saved localStorage container doesn't match the initial array, then the saved container is used.
However, I've changed the program drastically so that there are now multiple options to choose from and thus multiple arrays. Whichever option/array is chosen becomes the main container, and the main container still feeds out to the display output and the console output. See the updated program below...
multiple arrays = more complicated program
pseudo-code
The problem is that I am now having a difficult time figuring out how to implement localStorage on this new updated program. It was much easier previously when I only had 1 array to test against. Now, I can't just save the container any time a new entry is inputted (or removed) because the container can be any 1 of the 6 options.
Does anyone have any general ideas/pointers/suggestions as to what I can do?
The easiest (maybe not the most efficient) option would be to use an array of arrays. If before you had:
var container = ["a", "b", "c"];
localStorage.setItem("container", JSON.stringify(container));
You'd now have:
var container = [
["a", "b", "c"],
["d", "e", "f"]
];
localStorage.setItem("container", JSON.stringify(container));
Then for getting a single one in your new code, you'd just do:
var container = JSON.parse(localStorage.getItem('container')); //The same as before
var firstItem = container[0];
Hope this helps. Cheers
Why not just create a JSON object with multiple arrays, and save the entire stringified object in a localStorage variable instead of that single-dimensional array. It could even have a parameter referencing the selected container, and could be structured something like:
var containers = {
selectedContainer: "container1",
container1: ["text","contents","of","container1"],
container2: ["text","contents","of","container2"],
container3: ["text","contents","of","container3"],
container4: ["text","contents","of","container4"],
container5: ["text","contents","of","container5"],
container6: ["text","contents","of","container6"]
}
Content could then be pushed and popped to each of these container arrays, and the entire object saved in the single localStorage variable:
containers.container1.push("additional contents");
localStorage['containers'] = JSON.stringify(containers);
obj = JSON.parse(localStorage['containers']);
You could then reference the selected array with the selectedContainer parameter:
var container = (obj[obj.selectedContainer])

Javascript resetting an array

I'm having with some very strange behaviour when I try to reset an array; eg:
data.length=0;
where data is an array. I'll try and include only the relevant code here but basically what I;m doing is on each iteration of my program I'm populating the array with updated values and the array then is used in another function. But when I reset the array the function appears to get the values on the first iteration but none afterwards.
However when I don't reset the array then the function gets the values, but also the older values. I don't want this, as I only want the new updated values only. This is a code snippet:
var buffer = [['1',[0]],['2',[0]],['3',[0]],['4',[0]]];
var dataset = [];
ws.onmessage = function(evt){
dataset.length=0;
var distances = JSON.parse(evt.data);
console.log(distances);
for(var i=0; i<buffer.length; i++) {
if(buffer[i][0] == distances.miles) {
buffer[i][1][0]++;
}
//console.log(buffer);
dataset.push(buffer[i][1][0]);
draw();
//console.log(dataset);
}
}
The function uses the dataset array to redraw a chart.
I've tried to keep it simple here, but the full function is here.
I really don't know what's causing this unexpected behaviour.
EDIT:
console.log(dataset) shows the new updated values, but somehow dataset.length=0; is preventing the updated array to be used by the draw() function. As without the resetting of the array the array can be used by the draw() function.
EDIT:
I've tried to not reset the array but instead get the last 4 elements and put them in a new array and then send them to the draw(), but still the same odd behaviour:
x = dataset.slice(-4);
console.log(x);
draw();
But if I don't do that or don't clear the array, then draw() render a 'wrong' chart. I can't see what is wrong.
THE problem somehow seems to reside with the resetting of the array and that because of this it means the draw() function appears to be called only once at the first iteration.
Please, Please help
You don't need to set length at all. To clear a list of all value, just set it to an empty list:
dataset = [];
Looking at your code, I'm not sure, but why do you even have dataset? You don't ever read anything out of it, and you say you want to clear it every time thru the array.
Do you mean do to something like:
for(var i=0; i<buffer.length; i++) {
if(buffer[i][0] == distances.miles) {
buffer[i][1][0]++;
}
dataset.push(buffer[i][1][0]);
}
draw(dataset); // draw outside the loop, using dataset.

Categories