Cat
Cat

Reputation: 63

Why is my js for loop not working the way I expect?

So I have a bunch of inputs (81). Some of those inputs have a value, and some do not. Values are always 1-9. When a user clicks a button, I want to save all 81 inputs into a string. If an input has no value, it should be a zero in the string. This is what I have so far.

let board = document.querySelectorAll('input')
let newBoard = 0;

for (let i = 0; i < board.length; i++) {

    // if (i = 0 && board[i].value !== '') {
    //     newBoard = board[i]
    // }

    // if (i = 0) {
    //     newBoard = board[i]
    // }

    if (board[i].value === '') {
        newBoard += 0
    }
    else {
        newBoard += board[i].value
    }
}

newBoard = newBoard.substring(1)

The substring is to remove the first zero, as if I try to reset newboard on the first loop to first input (see above for // code), page stops working and just hangs/catches/whatever you want to call it.

If the first input has a value, then it works perfect. The string has a length of 81 characters. If the first input has NO value, the string is never 81. For example, if the first 3 inputs are blank, length is 78. If the first 2 inputs are blank, length is 79.

When I remove the substring, then if the first input is blank, string length is 81. If first 2 inputs are blank, length is 80. And if the first input has a value, length is 82.

Can someone advise what is going on? I've tried console.logging multiple places and I still can't figure out why/whats going on.

Upvotes: 1

Views: 68

Answers (3)

Culyx
Culyx

Reputation: 539

let board = document.querySelectorAll('input')
let newBoard = 0;

for (let i = 0; i < board.length; i++) {

    if (board[i].value === '') {
        newBoard += 0
    }
    else {
        newBoard += board[i].value
    }
}

newBoard = newBoard.substring(1);

let newBoard = 0; Javascript is going to treat this like a Number due to weak typing; as such your issue with empty values at the beginning is related to your code.

newBoard += 0 is also using a numeric zero, so when you get initial empty values, you literally just do 0 + 0 = 0

newBoard += board[i].value Once you get a non-empty value you get a ".value" return which is a string and starts to behave like you expect.

let board = document.querySelectorAll('input')
let newBoard = "";

for (let i = 0; i < board.length; i++) {

    if (board[i].value === '') {
        newBoard += "0"
    }
    else {
        newBoard += board[i].value
    }
}

So set newBoard to an empty string and set the 0 you concat as a string as well "0", you shouldn't need the substring any more.

Upvotes: 0

Cᴏʀʏ
Cᴏʀʏ

Reputation: 107626

It would appear that you have a mixture of integer addition and string concatenation going on. Try starting out newBoard as a string and concatenating a 0 string. You might have some type coercion going on under the hood.

let board = document.querySelectorAll('input')
let newBoard = '0';

for (let i = 0; i < board.length; i++) {
    if (board[i].value === '') {
        newBoard += '0'
    } else {
        newBoard += board[i].value
    }
}

newBoard = newBoard.substring(1)

You could also shorten this up to a one-liner, something like:

let newBoard = Array.from(document.querySelectorAll('input')).map(function (input) {
        return input.value || "0";
    }).join("");
    
console.log(newBoard);
<input type="text" value="3"/>
<input type="text" value=""/>
<input type="text" value="5"/>
<input type="text" value="6"/>

Upvotes: 0

TKoL
TKoL

Reputation: 13932

Here's basically what I think you want. making sure I'm only adding strings with strings, not numbers

function run() {
let board = document.querySelectorAll('input')
let newBoard = "";

for (let i = 0; i < board.length; i++) {

    // if (i = 0 && board[i].value !== '') {
    //     newBoard = board[i]
    // }

    // if (i = 0) {
    //     newBoard = board[i]
    // }

    if (board[i].value === '') {
        newBoard += "0"
    }
    else {
        newBoard += board[i].value
    }
}

// newBoard = newBoard.substring(1) // dont need this anymore
console.log('newBoard', newBoard);
}

document.querySelector('button').addEventListener('click', run);
<input type="text"><br>
<input type="text"><br>
<input type="text"><br>
<input type="text"><br>
<input type="text"><br>
<input type="text"><br>
<input type="text"><br>
<input type="text"><br>
<button>run</button>

Upvotes: 1

Related Questions