javascript form calculation returns NaN - javascript

I have an order form and a JavaScript which should calculate grand total from textbox (quantity*price), checkbox and radio, but I'm missing something because i receive a NaN error. Could somebody help me fix it?
Thanks a lot.
DEMO

Like many have commented, there are some serious short-comings to your code. I won't re-iterate these concerns, however, they are very important and you should learn as you are getting more acquainted with the technologies you are using.
The reason you are getting a NaN is this. Your fields object is an array. Your code populates the fields array at an arbitrary indices, i.e. fields[f] = 0;
When you populate the array for index, say 5, your code does this fields[5] = 0;. With this statement you went from having an empty array [], to having an array with 6 entries with the first 5 entries being defaulted to undefined [undefined, undefined, undefined, undefined, undefined, 0].
Now later in your code when you do the summation and add the arrays entries up (using eval having prepared a string) these ...undefined+0+undefined+8... are producing a Not A Number error.
Instead, one way to prevent this is to push entries onto the fields array like:
if (userInputs[f].value)
{
fields.push(userInputs[f].value);
}
else
{
fields.push(0);
}
push will add one entry to the end of the array. [] will become [0] if you push(0).

Related

Set value to an array in pentaho javascript step

i have some values in the input and i want to save them into an array but first i want to set the "0" index of the array to 0 and then in the 1,2,3,4 indexs add the value of the input but i can get to make it
before to set the values of the input i set the 0 to the position 0 of the array but it doesnt work
the thing is that i want to use only the first four number of the input_data into an array but first set the 0 position to 0 and then add 5,10,15,20.
so the final array would be 0,5,10,15,20
i set the index "0" of the array to 0 and the other indexes i fill them whit the incoming data.
This depends on how the data is reaching the 'Modified Java Script Value' step.
If it is one single row, with the string containing a "CSV", then Rohit.007 answer will suffice.
If you have multiple rows reaching the step, the Script will Repeat N(row) times. If you have 4 rows being fed to the step, this script will run 4 times, so you need some sort of restraint on the Variables, so you don't repeat some parts of the code.
Personally i would use something like this for Pentaho:
I generated 4 rows, with an add sequence , 1 to 4.
The first run of the script creates the array, pushes 0 and the value of the first row. The other iterations of the script just keep pushing whatever values are found on the specified row to this array (without "Re-declaring" it).
Remenber that the "For Each" command is kind of blurred in pentaho, since you're almost always dealing with multi-row tables, so whatever you do in scripts has to have some constraints on variables declarations.
You can try the below code.
let array = [];
array.push(0);
let string = '1,2,3,4';
array = array.concat(string.split(','));
let result = array.map(function (x) {
return parseInt(x, 10);
});
console.log(result);

Do undefined elements in an array have an impact in JS? [duplicate]

This question already has answers here:
Deleting array elements in JavaScript - delete vs splice
(29 answers)
Closed 4 years ago.
I couldn't find a question that specifically targets the issue I'm having hence this question is being asked.
I have an array that holds 5 numbers:
var numbers = [0,1,2,3,4];
Once a number is clicked on the frontend (website), the number is removed from the array using the below code:
delete numbers[1];
This removes the correct number but leaves a space where the number was (the space is undefined). I believe this is causing an issue. After a number is removed from the array, I use another function to randomly pick any of the remaining numbers in the array however it sometimes fails. After much thought, I've realized it may be because there are empty spaces in the array after a number is removed and as a result, the code fails to work due to the undefined element.
Is my analogy correct or am I mistaken?
(I have also attempted to use the splice method to remove the number however that then causes an issue with the length of my array because if I later want to remove another number, it removes the wrong one due to the numbers moving around etc).
What you'd want to use is splice
In your specific case, numbers.splice(1,1)
You're correct that delete replaces one of the values in the array with undefined, and does not change the array length. Later on when you randomly choose an element from the array, you can wind up getting that undefined value, because it's still taking up a slot in the array:
var numbers = [0,1,2,3,4];
delete numbers[3];
console.log(numbers)
Instead use splice, which removes the item from the array completely:
var numbers = [0,1,2,3,4];
numbers.splice(3,1) /// remove one element starting at index 3
console.log(numbers)
if I later want to remove another number, it removes the wrong one due to the numbers moving around
You do need to choose one behavior or the other. If you need to preserve indexes as is, then continue to use delete, leaving the undefined values in the array, and rewrite your "choose one at random" function to never pick undefined values:
// start with some undefined values:
var numbers = [0, 1, undefined, undefined, undefined, 5]
var pickRandom = function(numbers) {
// make a copy of the array, removing undefined elements:
var definedValues = numbers.filter(function(item) {
return item !== undefined;
});
if (definedValues.length === 0) {return false}
//choose one at random:
return definedValues[Math.floor(Math.random() * definedValues.length)]
}
// test it:
console.log(pickRandom(numbers));
console.log(pickRandom(numbers));
console.log(pickRandom(numbers));
console.log(pickRandom(numbers));
(...but note that this suggests that a simple array is the wrong data structure to use here; you may be better off with an array of objects each with an explicit ID, so you can reference specific ones as needed without worrying about keeping the array index the same.)
If you mean to actually remove the element from the array, leaving your array with 4 elements, then you can use
numbers.splice(1);
This will remove the element in the index 1 from the array and return the section of the new array.

Looping over undefined array keys

Problem:
I have a DB containing math exercises, split by difficulty levels and date taken.
i want to generate a diagram of the performance over time.
to achieve this, i loop through the query results, and ++ a counter for the level and day the exercise was taken.
example: level 2 exercise was taken at 01.11.2015.
this.levels[2].daysAgo[1].amountTaken++;
with this, i can build a diagram, where day 0 is always today, and the performance over days is shown.
now levels[] has a predefined amount of levels, so there is no problem with that.
but daysAgo[] is very dynamic (it even changes daily with the same data), so if there was only one exercise taken, it would wander on a daily basis (from daysAgo[0] to daysAgo[1] and so on).
the daysAgo[] between that would be empty (because there are no entries).
but for evaluating the diagram, i need them to have an initialized state with amountTaken: 0, and so on.
problem being: i can't know when the oldest exercise was.
Idea 1:
First gather all entries in a kind of proxy object, where i have a var maxDaysAgo that holds the value for the oldest exercise, then initialize an array daysAgo[maxDaysAgo] that gets filled with 0-entries, before inserting the actual entries.
that seems very clumsy and overly complicated
Idea 2:
Just add the entries this.level[level].daysAgo[daysAgo].amountTaken++;, possibly leaving the daysAgo array with a lot of undefined keys.
Then, after all entries are added, i would loop over the daysAgokeys with
for (var i = 1; i < this.maxLevel; i++) { // for every level
for (var j = 0; j < this.levels[i].daysAgo.length; j++) {
but daysAgo.lengthwill not count undefined fields, will it?
So if i have one single entry at [24], length will still be 1 :/
Question:
How can I find out the highest key in an array and loop until there, when there are undefined keys between?
How can i adress all undefined keys up until the highest (and not any more)?
Or: what would be a different, more elegant way to solve this whole problem altogether?
Thanks :)
array.length returns one higher than the highest numerical index, so can be used to loop though even undefined values
as a test:
var a=[]
a[24]=1
console.log(a.length)
outputs 25 for me (in chrome and firefox).

javascript array unsure property array[index] = true/false

I came across this, understood it but still did not know what javascript property it was:
var array = [];
array[1] = true;
array[5] = true;
console.log(array) #=> [true, true]
array[0] #=> undefined
array[1] #=> true
array[2] #=> undefined
array[5] #=> true
Can someone explain this for me? Thanks
Standard arrays in JavaScript aren't really arrays at all, and one effect of that is that they're inherently sparse. That is, an array can have empty slots in it.
That's what you're creating there. After your first three lines, you have an array with two entries in it, at indexes 1 and 5, and a bunch of completely empty slots (indexes 0, 2, 3, 4). Its length property would be 6. When you try to retrieve an element that doesn't exist from an array, you get the value undefined. (This is just a specific case of JavaScript's general behavior: If you try to retrieve an object property that doesn't exist, you get the value undefined.)
The output of console.log with a sparse array will vary depending on what the implementation of console.log does with them. The comments on the question suggest that there are various different ways the console may show the array. You might look at using console.log(array.join()) to get more consistent results. That would give you ,true,,,,true, because it shows blanks for array entries that don't exist (or that contain the value undefined, but in your case, they don't exist).

Array containing objects has wrong length

I have an array like:
errors = [ {...}, {...}, {...} ]
It's an instanceof array, yet it only returns 1 for .length?
Relevant code:
if(data.error){
errors.push({'element':ele,error:data.error});
}
//Above is looped a few times and there are N number of errors now inside
console.log(errors) //Returns 2+ objects like {...}, {...}
console.log(errors.length) //Returns 1
For Uzi and Muirbot, here's the errors array:
[
Object
element: b.fn.b.init[1]
error: "You must enter "example" into the field to pass"
__proto__: Object
,
Object
element: b.fn.b.init[1]
error: "Crap!"
__proto__: Object
It is correct, this code:
var errors = new Array();
errors.push({'element':'ele', error:'data.error'});
...adds ONE object to the array. The object has two properties.
It's possible your code is executing in an order other than what you're expecting. ie, when you log both errors and errors.length, errors does contain only 1 object. But after that you are adding to the errors array, and only after that are you looking at the console. At that point you could see a larger array in errors for two reasons - first, your actual code isn't logging errors but some object that contains errors. In that case the console display is live, and will show you not what was in errors at the time, but what is in it now. Alternatively, the console could just be taking some time to log errors.
Without more code I can't be sure if this is the case. But you could verify it by replacing console.log(errors); with console.log(errors[1]);. If errors is really only 1 long at the time, it will log undefined.
The problem was that Chrome's Web Inspector's console.log is an async event. So, the length was a property lookup so it gave that back instantly, but the object with two items inside was held off until the rest of the events had fired.
In the future I, and others with this issue, should use debugger; instead.
is it an Array object or something that resembles it?
arrays do work:
> a = [{a:1}, {b:2}]
[Object, Object]
> a.length
2
you'll have to provide more code.
and now that you've provided the relevant code, the correct answer is what Steve Wellens said (which was downvoted, by the way).
Array.push adds a single element, objects may have more than one key but they're still a single object so your real case was different from your original example, which of course works.
another possibility:
> a = []
[]
> a.length = 2
2
> a
[]
> a.length
2
> a instanceof Array
true

Categories

Resources