SuiteScript / JavaScript Array Indexing Issues - javascript

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.

Related

Aggregate values in a javascript grouped object based on conditions

I am using IE 11.
I have an object array that is grouped using the lodash library. I want to be able to query the object and based on certain conditions come up with sums/counts. So for example, I have this object array.
I would like to have the result seen below but in an object like the image above
As you can see, each company in the group should have certain values based on the following criteria
How many times does 'company x' have a Total Count >3?
How many times does 'company x' have expectingFunding eq ‘Yes’>
How many times does 'company x' have fundedOnIKNS eq ‘No’?
I've tried quite a bit in the last couple of days but not success. I first declared 2 arrays so I can capture the unique values of company name and program. I also created an object to update when conditions were met. The only successful thing I was able to get was to keep it in an grouped object. All the values in the new object were wrong.
Here's an excerpt of the code:
const companiesSummary = {};
for (const company of Object.keys(myData)) {
companiesSummary[company] = {
totalCount: 0,
expectedFunding: 0,
IKNSFunding: 0,
};
for (const { TotalCount, expectedFunding, fundedOnIKNS } of myData[company]) {
companiesSummary[company].totalCount += TotalCount;
companiesSummary[company].expectedFunding += expectedFunding === "Yes";
companiesSummary[company].fundedOnIKNS += fundedOnIKNS === "Yes";
}
}
I get the error,
TypeError: myData[company] is not iterable
Here's a link to the pen
I would still like the result to be in an object array, so I can create an html table later. Any help would be much appreciated. Thank you!
Your code isn't working because you're taking myData, an array, accessing myData[company], an object (company is 0, 1, ...), and you can't iterate through an object with for...of. myData is definitely not the same object in your screenshot.
Your code excerpt might work if your myData object were the object in your screenshot.

why are my javascript floating point numbers getting sliced up?

I have an array filled with latitude and longitude pairs pushed like this
doneDotsA.push(lat+"|"+lon);
the values can look like 51.5 or -0.11666666666666667, etc.
then the array is stored in a cookie as an array.
when I try to read the cookie contents it looks like this when In examine it
alert('doneDotsA='+doneDotsA.toString());
yields results like this:
doneDotsA=51.5|-0.11666666666666667
so far so good. however when I try to extract the values like this
for (var t = 0; t < doneDotsA.length; t++) {
alert('val='+doneDotsA[t]);
}
the alert shows 'val=5' then 'val=1' then 'val=.' then 'val=5' etc. somehow reading only one character at a time instead of returning the full number as I'd expect it to do.
does saving an array into a cookie do something to the numbers?
any ideas?
stored in a cookie as an array
Cookies are always stored and retrieved as a string, unless you use custom code to rebuild it into an array after the fact.
A solution like this could be to take your latitude and longitude and put them into a JSON object for serialization and storage in the cookie. Then you can parse them into objects when the site loads.
var coords = {
points:[
{lat:12.4444446,lon:44.55555},
{lat:12.4444446,lon:44.55555}
]
};
var serialized = JSON.stringify(coords);
toStore(serialized);
Then you can just set it to local store or to anyplace you can store a string.
var myLoaded = fromStore();
var coords = JSON.parse(myLoaded);
coords.points.each(function(coord) {
// do something with points.
});
You should then be able to do something with the points you saved.
One note: you might want to check that myLoaded is not an empty string or wrap parse in a try/catch block. A poorly formed structure will throw an exception.

Javascript pushing into array issue with parsing data from an object

I am currently working on a project what requires me to use the US Census Bureau API. I have most of my code working on my portion of the project however, I am having a small issue that I do not understand. What I am trying to do is take a 113 objects, parse one property from each of those objects, and then place that property, all 113, into an array. Like I said, I almost have my code working. Below is what does work:
for (var i = 0; i <= response.features.length; i++){
var dataPoint = response.features[i].properties.B19013_001E;
console.log(dataPoint);
}
The above code will print out all 113 points that I need to the console. (For those that are curious, the B19013_001E is median household income and that is the data that I want for basically a 113 different 'areas' within a county.)
Now, the code does what I want but now when I make the array portion:
var dataArray = [];
for (var i = 0; i <= response.features.length; i++){
var dataPoint = response.features[i].properties.B19013_001E;
dataArray.push(dataPoint);
}
console.log(dataArray);
When I console log my array, I only get this error message:
play.js:93 Uncaught TypeError: Cannot read property 'properties' of undefined
What I don't understand is how come I can get all 113 points that I need individually to the console but I have an issue when I am putting them into the array? One thing that I thought of was that maybe one of the points is not present? But when I look at the console logging of 113 points I get nothing as null or undefined. Any help will be great and thank you!
You should use Array.map:
var dataArray = response.features.map(function(feature) {
return feature.properties.B19013_001E;
})
You are getting that error because <= puts the last iteration outside of the bounds of your data collection. You could just change that to <

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!

meteor minimongo getting inconsistent collection.findOne() results

I've been trying to debug a chunk of code for some hours now, banging my head against the wall, and finally pinpointed my issues to a place in the code where assigning the results of a collection.findOne() call to a variable is giving me different data than what I see with a console.log() of the same findOne() on the previous line.
prePostState = function(thisStID) {
console.log(Students.findOne({_id:thisStID}));
var stTemp = Students.findOne({_id:thisStID});
console.log(stTmp);
var testsTemp = stTmp.tests;
The collection object has a 'tests' array. In this instance, the array contains 3 objects as its elements.
While both the console.log() lines return something like this
Object {_id: "eXf9dqQbaemKS24Ti", name: "Student,Name", group: "none", site: "SiteName", tests: Array[3]}
Expanding each shows different data. The first one shows the correct tests: Array[3], the second one shows tests: Array[1], and the single element in that array also has data that is different from the matching element in the full array.
----Update----
Doing some further testing, I've changed the code a bit.
prePostState = function(thisStID) {
console.log(Students.find({_id:thisStID}).fetch()); //1
var stTmp = Students.find({_id:thisStID}).fetch();
console.log(stTmp); //2
console.log(stTmp[0].tests.length); //3
for(var i = 0; i < stTmp[0].tests.length; i++) {
console.log(stTmp[0].tests[i]); //4
}
1 Returns:
[Object]
0: Object
_id: "AqLHB8hT8GxzQ7zyD"
group: "none"
name: "Student,Name"
site: "SiteName"
tests: Array[3]
2 Returns:
[Object]
0: Object
_id: "AqLHB8hT8GxzQ7zyD"
group: "none"
name: "Student,Name"
site: "SiteName"
tests: Array[1]
3 Returns:
3
The for loop at 4 repeats three times and prints out each of the three objects in the tests array.
Obviously this means I can access the data I need. Instead of
var testArray = stTmp.tests;
Which leaves me with an array with only a single element, I will just have to get the length of stTmp.tests, and then use a for loop to access each element by index and insert them into the testArray variable.
So I can continue on, but I still don't understand the behavior I'm seeing. I'm on a bit of a timeline to keep making progress at this point, but when I have some time I may revisit this and try and replicate it in a meteorpad or other form that I can share the full code with.
1) If you modify a return value from Minimongo, don't expect it to persist. Minimongo was specifically written this way, so you are forced to use update operators to update the values.
2) The correct projection API is Coll.find({..selector..}, {fields:{..projection..}})

Categories