JavaScript - Nested FOR loop executing twice - javascript

I have a nested FOR loop that iterates over an object, and updating variables or attributes based on conditions. The last 'IF' on this loop formats a date and updates the field accordingly. For some reason the final line causes the loop to iterate twice, therefore updating the 'formattedDate' variable twice (in the object, there is only one single element with the 'childTag' = 'date'. Any help is appreciated!
for (let i = 0; i < submitFormData.tabs.length; i++) {
for (let j = 0; j < submitFormData.tabs[i].elements.length; j++) {
if (submitFormData.tabs[i].elements[j].childTag == "project_name") {
projectName = submitFormData.tabs[i].elements[j].value;
} else if (submitFormData.tabs[i].elements[j].childTag == "location_store") {
locationStore = ' #' + submitFormData.tabs[i].elements[j].value;
} else if (submitFormData.tabs[i].elements[j].childTag == "location_street") {
locationStreet = submitFormData.tabs[i].elements[j].value;
} else if (submitFormData.tabs[i].elements[j].childTag == "location_city") {
locationCity = submitFormData.tabs[i].elements[j].value;
} else if (submitFormData.tabs[i].elements[j].childTag == "location_state") {
locationState = submitFormData.tabs[i].elements[j].value;
} else if (submitFormData.tabs[i].elements[j].childTag == "location_zip") {
locationZip = submitFormData.tabs[i].elements[j].value;
} else if (submitFormData.tabs[i].elements[j].childTag == "date") {
if (submitFormData.tabs[i].elements[j].value != "") {
console.log(submitFormData)
date = (submitFormData.tabs[i].elements[j].value.substring(0, 10));
formattedDate = (date.substring(5, 11) + '-' + date.substring(0, 4));
console.log(formattedDate, 'formatted date')
submitFormData.tabs[i].elements[j].value = formattedDate;
}
}
}
}
Sample of Object

I see that in the loop you manipulate the list which you iterate over.
submitFormData.tabs[i].elements
It would be better to make a copy of it and iterate over it.
const newSubmitFormData = [...submitFormData.tabs[i].elements]
for (let j = 0; j < newSubmitFormData .length; j++) { /* your code */ }

Related

recursive function returns the same value each time

So I have a checkers game, and I am trying to get it so that you can jump over multiple spaces. It works if you jump the max amount of spaces, but if you don't, say you can jump over two spaces, and you choose to jump over only one, it still removes both pieces even though you only jumped over one of the pieces. I think the problem has is inside the checkForJump() function, and it seems like every time the function is called, it returns the same array, any help would be appreciated.
function checkForJump(buttonSelected, remove, isRoot) {
if(isRoot)
{
clearAvailableMoves();
switchPiece();
}
let adjacentValue = 0;
let jumpNotValid = false;
let RemoveTiles = remove;
for (let i = 0; i < adjacentTileValues.length; i++) {
adjacentValue = adjacentTileValues[i];
if (board.value[adjacentValue + buttonSelected] == enemyPiece && board.value[buttonSelected + (adjacentValue * 2)] == empty) {
if (isSpaceAlreadyInArray(buttonSelected + adjacentValue * 2, i) == false) {
RemoveTiles.push(buttonSelected + adjacentValue);
let tile = new jumpTile(buttonSelected + (adjacentValue * 2));
RemoveTiles.push(buttonSelected + adjacentValue);
console.log("removeTiles" + RemoveTiles);
for (let k = 0; k < RemoveTiles.length; k++) {
tile.tilesToRemove.push(RemoveTiles[k]);
}
console.log("tile.tilesToRemove: " + tile.tilesToRemove);
availableSpaces[i].push(tile);
checkForJump(buttonSelected + (adjacentValue * 2), RemoveTiles,false);
console.log("available spaces = " + availableSpaces);
}
}
}
};
Here is some of the other code, relating to that could also be the source of the problem
function jumpTile(tileID) {
this.tilesToRemove = [];
this.tileID = tileID;
};
let numBlackPieces = 12;
let numWhitePieces = 12;
let adjacentTileValues = [7, 9, -7, -9];
let availableSpaces = [
[],
[],
[],
[]
];
function checkValidSpace(buttonPressed, piece) {
// if button is adjacent to selectedbutton
if (buttonPressed == selectedButton + 7 || buttonPressed == selectedButton + 9 || buttonPressed == selectedButton - 9 || buttonPressed == selectedButton - 7) {
return true;
} else {
let valid = false;
// checks if there is a valid jump
checkForJump(selectedButton,[],true);
// foreach of the possible tiles, if the button pressed is one of them than remove all pieces in that tiles remove list
for (let i = 0; i < availableSpaces.length; i++) {
for (let j = 0; j < availableSpaces[i].length; j++) {
if (buttonPressed == availableSpaces[i][j].tileID) {
valid = true;
console.log("availableSpaces[" + i + j + "] is " + availableSpaces[i][j].tileID + "");
remove(availableSpaces[i][j].tilesToRemove);
return true;
}
}
}
if (valid == false)
return false;
}
}
function checkForJump(buttonSelected, remove, isRoot) {
if(isRoot)
{
clearAvailableMoves();
switchPiece();
}
let adjacentValue = 0;
let jumpNotValid = false;
let RemoveTiles = remove;
for (let i = 0; i < adjacentTileValues.length; i++) {
adjacentValue = adjacentTileValues[i];
if (board.value[adjacentValue + buttonSelected] == enemyPiece && board.value[buttonSelected + (adjacentValue * 2)] == empty) {
if (isSpaceAlreadyInArray(buttonSelected + adjacentValue * 2, i) == false) {
RemoveTiles.push(buttonSelected + adjacentValue);
let tile = new jumpTile(buttonSelected + (adjacentValue * 2));
RemoveTiles.push(buttonSelected + adjacentValue);
console.log("removeTiles" + RemoveTiles);
for (let k = 0; k < RemoveTiles.length; k++) {
tile.tilesToRemove.push(RemoveTiles[k]);
}
console.log("tile.tilesToRemove: " + tile.tilesToRemove);
availableSpaces[i].push(tile);
checkForJump(buttonSelected + (adjacentValue * 2), RemoveTiles,false);
console.log("available spaces = " + availableSpaces);
}
}
}
};
function isSpaceAlreadyInArray(spot, arrayIndex) {
let SpaceAlreadyInArray = false;
for (let j = 0; j < availableSpaces[arrayIndex].length; j++) {
if (availableSpaces[arrayIndex][j].tileID == spot) {
SpaceAlreadyInArray = true;
}
}
return SpaceAlreadyInArray;
}
function clearAvailableMoves() {
for (let i = 0; i < availableSpaces.length; i++) {
availableSpaces[i].pop();
}
}
function remove(removeList, button) {
for (let i = 0; i < removeList.length; i++) {
board.value[removeList[i]] = empty;
board.buttons[removeList[i]].textContent = empty;
if (piece == black) {
numBlackPieces--;
checkForWin(numBlackPieces);
} else if (piece == white) {
numWhitePieces--;
checkForWin(numWhitePieces);
}
}
clearAvailableMoves();
};

TypeError in JavaScript when setting the Y position

When running this code I currently getting the error "TypeError: Invalid value for y-coordinate. Make sure you are passing finite numbers to setPosition(x, y)." all of my functions do work are are declared properly. When I use a println and print out letYPos it prints out "NaN" but when I call the function again it prints out the correct value. Does anyone know how I can fix this or if there even is a way to fix this?
var count = 0;
var letYPos = 0;
var y = 3;
function testing()
{
var letXPos = 25;
letYPos += 75;
if (count == 6)
{
println("You have ran out of guesses, the correct anwser was: " + secretWord);
return;
}
var input = readLine("Enter your word: ");
if (input == null)
{
println("You have to enter a word! ");
return;
}
if (input.length != 5)
{
println("That is not a five letter word, please try again.");
return;
}
var x = 3;
for (var i = 0; i < input.length; i++)
{
if (input.includes(secretWord.charAt(i)))
{
var index = input.indexOf(secretWord.charAt(i));
}
if (index == 0) { yellow(3, y ) }
if (index == 1) { yellow(83, y ) }
if (index == 2) { yellow(163, y) }
if (index == 3) { yellow(243, y) }
if (index == 4) { yellow(323, y) } index = null;
}
for (var i = 0; i < input.length; i++)
{
if (input.charAt(i) == secretWord.charAt(i))
{
green(x, y);
}
x += 80;
}
y += 80;
for (var i = 0; i < input.length; i++)
{
for (var a = 0; a <= 5; a++)
{
var txt = new Text(input.charAt(a), font);
txt.setPosition(letXPos, letYPos);
add(txt);
letXPos += 80;
}
}
if (input == secretWord)
{
println("That's Correct, Congratulations!");
return;
}
count++;
setTimeout(testing, 100);
}

Pop up a warning when the same item is entered twice on a sales order when the order is created/edited

I am trying to do a pop-up warning before the sales order is saved if the exact same item is entered twice when the order is created/modified on Netsuite. However, there is no window popping up and I am not sure what is wrong with the script. Here is what I got:
function validateitem (type){
var flag = true;
var numLine = nlapiGetLineItemCount('item');
itemArr = [];
if (type == 'item' && numLine > 0) {
for(var i = 0; i < numLine; i++) {
var itemSO = {};
itemSO.id = nlapiGetLineValue('item','item',i);
if (itemSO.id != null && itemSO.id !=''){
for (var j = 0; j < numLine; j++){
if(itenArr.indexOf(itemSO[i].id) === -1) {
itemArr.push(itemSO[i].id);}
else{
if (!confirm('You have entered a duplicate item for this sales order. Continue?'))
{
flag = false;
}
}
}
}
}
}
return flag;
}
Can somebody help, please?
Here is a slightly edited version:
function validateitem (){
var flag = true;
var numLine = nlapiGetLineItemCount('item');
itemArr = [];
if (numLine > 0) {
for(var i = 1; i <= numLine; i++) {
var itemSO = nlapiGetLineItemValue('item','item',i);
if (itemSO != null && itemSO !=''){
for (var j = 1; j <= numLine; j++){
if(itemArr.indexOf(itemSO[i]) === -1) {
itemArr.push(itemSO[i]);}
else{
flag = false;
}
}
}
}
}
if (flag == false){
alert('You have entered the same item twice.Continue?');
}
return flag;
}
This is the complete after-edit code that works:
function validateitem (){
var flag = true;
var numLine = nlapiGetLineItemCount('item');
itemArr = [];
if (numLine > 0) {
for(var i = 1; i <= numLine; i++) {
var itemSO = nlapiGetLineItemValue('item','item',i);
if (itemSO != null && itemSO !=''){
for (var j = i+1; j <= numLine; j++){
var itemSOplus = nlapiGetLineItemValue('item','item',j);
if(itemSO === itemSOplus) {
flag = false;
}
}
}
}
}
if (flag == false){
alert('You have entered the same item twice.Continue?');
}
return flag;
}
Thanks to Krypton!!
As per SuiteAnswers ID 10579, there are no paramters passed to the saveRecord client event. Therefore when your code checks the following:
if (type == 'item' && numLine > 0)
it finds that type equals undefined, so the condition is not met and the code will jump straight down to return flag which has been set to true.
Also note that in SuiteScript 1.0, line indexes start from 1 - not 0 as your code seems to assume.
EDIT - adding comment to form part of this answer:
I'd like to understand your logic behind itemSO[i] - as itemSO is not an array. Why not just compare the item from the current line of the inner loop with the current line of the outer loop and set the flag false if they match? Also, the inner loop need only start from j = i + 1 as the previous lines would have already been compared.

Javascript loop within a loop-only executes first time

Please see my js validation function below.
function validate_submit(PassForm) {
var bGo = false;
var rankcount = document.getElementById('rankCount').value;
var j = 0;
var iRankcount0 = document.getElementById('indRankcount0').value;
var iRankcount1 = document.getElementById('indRankcount1').value;
var iRankcount2 = document.getElementById('indRankcount2').value;
var ijs = 0;
var itemp = ijs;
for (i = 0; i < rankcount; i++) {
alert("begin i = " + i);
if (i == 0) {
indRankcount = iRankcount0;
}
else if (i == 1) {
alert('indRankcount: ' + indRankcount);
indRankcount = iRankcount1;
alert('iRankcount1: ' + iRankcount1);
alert('indRankcount: ' + indRankcount);
}
else if (i == 2) {
indRankcount = iRankcount2;
}
alert('before sec loop indRank: ' + indRankcount);
alert('before sec loop itemp: ' + itemp);
for (k = itemp; k < indRankcount; k++) {
alert('in check bGo');
if (document.getElementById("selectedScore" + i + k).checked) {
bGo = true;
j++;
} //if
} //for indRankcount - k loop
if (bGo) {
if (i == 0) {
par = (Math.ceil(indRankcount / 4));
}
else if (i == 1) {
par = (Math.ceil((iRankcount1 - iRankcount0) / 4));
alert('1: ' + par);
}
else if (i == 2) {
par = (Math.ceil((indRankcount2 - iRankcount1) / 4));
}
if (j == par) {
j = 0;
bGo = false;
itemp = indRankcount;
alert("itemp = " + itemp);
continue;
}
else {
alert('25% criteria not met.');
return false;
}
}
else { //else to check bGo
alert('Atleast one box need to be selected.');
return false;
}
j = 0;
bGo = false;
itemp = indRankcount;
alert("loop ends: i =" + i);
} //for rankcount - i loop
res = window.confirm('Are you sure you want to proceed with the selection?');
if (res) {
return true;
}
else {
return false;
}
} //end of validate
Problem is when i=0, it executes fine. But when i=1, second loop (K) doesn't execute(we switched the variable to constant- it works for either itemp or indRankcount.Just one number did it.) It totally skips. Help please! Thank you!
After the inner loop (which uses "k"), there is a "itemp = indRankcount;" line. I guess this cause the issue.
On the first run the "itemp" is 0 so the inner loop step in, but on the second run this value more or equal with the "indRankcount", because you call the code before.
What values are stored in "iRankcount0", "iRankcount1" and "iRankcount2"?
Try to print the "itemp" and "indRankcount" values before the 2. loop.
Updated, try this before the k loop, it will show why the k not starts on the 2. execution.
Console.log(i + "loop:: " + itemp + " val (k first val), " + " indRankcount " + val (k end val));

Why doesn't this .push work? (javascript)

var text = "some text jjke kjerk jker helmi kjekjr helmi ekjrkje helmi";
var myName = "helmi";
var hits = [];
for (var i = 0; i < text.length; i++) {
if (text[i] === 'h') {
for (var j = i; j < text[i] + myName.length; j+=1) {
}
hits.push('text[j]');
}
};
if (hits.length === 0) {
console.log("Your name wasn't found!");
}
else {
console.log(hits);
}
I want it to find "myName" in the "text", and push it. But it only pushes whatever I put in the parenthesis after hits.push. What is wrong with this code?
But it only pushes whatever I put in the parenthesis after hits.push
Exactly, which is why you don't want to put a string in there:
hits.push('text[j]');
but a variable value:
hits.push(text[j]);
for (var i = 0; i < text.length; i++) {
if (text[i] === 'h') {
for (var j = i; j < text[i] + myName.length; j+=1) {
hits.push(text[j]);
}
}
your code has bracket problem and in some case you're doing wrong .
You can use split function. It gives you an opportunity to check your name word by word instead of checking your name character by character.
var text = "some text jjke kjerk jker helmi kjekjr helmi ekjrkje helmi";
var myName = "helmi";
var hits = [];
var texts = text.split(" ");
for (var i = 0; i < texts.length; i++) {
if (texts[i] === myName) {
hits.push(texts[i]);
}
}
if (hits.length === 0) {
console.log("Your name wasn't found!");
}
else {
console.log(hits);
}
Simple example for what you are trying to do is
if(text.indexOf(myName)!=-1)
console.log(myName);
else
console.log("Your name wasn't found");

Categories