Parsing a JSON object of arrays gives different results in IE9 - javascript

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!

Related

How do I split/slice a leaflet L.layerGroup into mutliple L.layerGroup(s)?

I'm using leafletjs to draw a line from marker to marker. But the markers are grouped into sets, each with its own name. I get the data from MySQL with PHP and create;
var OBJMarkerList = L.layerGroup([W0DLK01,W0DLK02,W0DLK03,W0DLK04,W0DLK05,WA0TJT01,WA0TJT02,WA0TJT03,WA0TJT04,WA0TJT05,WA0TJT06,WA0TJT07,WA0TJT08,WA0TJT09,]);
Notice the name changes.
But I need to pass it into a function one part at a time in order to change the color of the line. So while I have the above OBJMarkerList what I really need is;
var W0DLKOBJMarkerList = L.layerGroup([W0DLK01,W0DLK02,W0DLK03,W0DLK04,W0DLK05,]);
And another for the other set of values, WA0TJTOBJMarkerList.
I created an array of the names;
const allnameBounds = (['W0DLKOBJMarkerList','WA0TJTOBJMarkerList']);
But its literally just the names and the function (below) will not accept it as input to convert to the x,y coordinates I need.
function connectTheDots(data){
var c = [];
for(i in data._layers) {
var x = data._layers[i]._latlng.lat;
var y = data._layers[i]._latlng.lng;
c.push([x, y]);
}
return c;
}
How can I split the L.layerGroup into two or any number of parts based on the variable names given? There will usually be more than just two, this is a simplified example.
I tried iterating over the allnameBounds array in all the usual ways and while the looping works to extract the name, the function does not process it like the leaflet object it is.
I also went back to the MySQL/PHP and tried to create a stand alone for each name, that's fine but I still need another list of the L.layerGroup names to iterate over.
Spliting or slicing the combined seemed the only answer. I just don't know how to get there.
Can someone give me a better way or show me how to split the overall list?

SuiteScript / JavaScript Array Indexing Issues

I am working on dynamically generating XML for printing labels. I have an array of values generated with map, the format of this array should end up as such:
[[val1a, val1b, val1c],[val2a,val2b,val2c],[val3a,val3b,val3c]]
I am unable to log to the browser console in this application, so must use provided logging APIs to view the actual values of the array at any given point. The format presented by logging is as such:
val1a,val1b,val1c,val2a...
The values are generated like so:
for(var i = 0; i < lines; i++) {
for(var j = 0; j < quantity; j++){
smCnts.push([i]);
}
}
Where i is the line number of the specific "record", and j is iterating over the quantity, pushing the line number to the array smCnts. Resulting in a dataset like this (assuming line 1 has a quantity of 3, and line 2 has a quantity of 2 etc.):
[[1], [1], [1], [2], [2], [3]]
This array is then mapped using a function that gets values from the lines:
var smLbls = smCnts.map(getData);
Resulting in something like the first array listed in this question.
The problem results when trying to index the array for a specific value:
var foo = smLbls[1];
This returns nothing, I don't even know if it returns null as the logging api returns only: .
However, logging smLbls returns the first mentioned array as described in the second code snippet. What would be causing this issue? I need to be able to get the index of the index of an array like so:
var bar = smLbls[1][3];
Everything else is working as expected, I am just unable to access this data for whatever reason, maybe I am not understanding JavaScript fully?
I am unable to log to the browser console in this application, so must use provided logging APIs to view the actual values of the array at any given point. The format presented by logging is as such:
My advice, use the logs to extract a snapshot of your data:
nlapiLogExecution('debug', 'sample', JSON.stringify(data));
...and work in the browser.

JSON.parse(json_string_from_php) produces weird array

I'm having a bit of difficulty with transferring a JSON object from the server to the client-side javascript
I have a rows of data fetched from MySQL query stored into $result
Here's the code:
var json = '<?= json_encode($result->fetch_all()) ?>';
var word_list = JSON.parse(json);
console.log(word_list); //index.php:23
console.log(json); //index.php:24
This is the result in chrome console:
Can someone tell me:
1. Why line 23 shows length of 5 when folded, then only show length of 4 when unfolded?
2. Where did word5 go? FYI, the word that disappears changes every time I refresh.
I am able to reproduce your screenshot.
I purposely hovered over the little "i" to reveal its tooltip. It states "Object state below is captured upon first expansion.
This means that if you print the array, don't expand it, modify the array (say with a pop()) then when you expand it you will see the modified array.
Demo: JSBin
console.log logs your state of the object to the console when it is hitting the console.log while inspecting the array (or any object) shows you the current state of it.
var a = [1,2,3,4,5].map(function(){ return new String(); });
console.log(a);
a.pop();

How do I use #DbLookup results to populate a Readers field in xpages?

db = new Array("myserver", "myfolder\\mydb.nsf")
dir = getComponent("Dir").value;
div = getComponent("Div").value;
lu = #DbLookup(db, "ManagerAccess", dir + "PP" + div, "DTManagers");
var a = [];
a.push(lu);
var item:NotesItem = docBackEnd.replaceItemValue('FormReaders', #Unique(a));
item.setReaders(true);
That code is on the querySaveDocument ssjs. The result I get from the #DbLookup (when I put in a computed field) look like this:
Pedro Martinez,Manny Ramirez,David Ortiz,Terry Francona
I tried doing an #Explode(#Implode) thing on it, but it doesn't seem to work.
The error I get in the browser just tells me that the replaceItemValue line is broken.
To test it, I pushed several strings one at a time, and it worked correctly populating my FormReaders field with the multiple entries.
What am I doing wrong?
I see several problems here:
A. In cases as described by you #Dblookup in fact would return an array. If you push an array into a plain computedField control it will exactly look as that you wrote:
value1, value2, ..., valueN
A computedField doesn't know anything about multiple values etc, it just can display strings, or data that can be converted to strings.
If you want to test the return value you could try to return something like lu[0]; you then should receive the array's 1st element, or a runtime error, if lu is NOT an array. Or you could ask for the array's size using lu.length. That returns the number of array elements, or the number of characters if it's just a plain string.
B. your code contains these two lines:
var a = [];
a.push(lu);
By that you create an empty array, then push lu[] to the first element of a[]. The result is something like this:
a[0] = [value1, value2, ..., valueN],
i.e. a is an array where the first element contains another array. Since you don't want that, just use #Unique(lu) in your replaceItemValue-method.
C. I don't see why replaceItemValue would throw an error here, apart from what I wrote in topic B. Give it a try by writing lu directly to the item (first without #Unique). That should work.
D. for completeness: in the first line you used "new Array". A much better way to define your db parameters is
var db = ["myserver", "myfolder/mydb.nsf"];
(see Tim Tripcony's comment in your recent question, or see his blog entry at http://www.timtripcony.com/blog.nsf/d6plinks/TTRY-9AN5ZK)

Changing the variables of a class in OOP in 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();

Categories