0

I'm trying to display all elements of an array, by iterating through the arrray, but after I chose the file (from the input), the element in page changes to : "unidentified". Why?

function getElement() {
    console.log('sfgsdf')
    document.getElementById('files').onchange = function() {
        console.log('sfgsdf')
        let file = this.files[0];
        let reader = new FileReader();
        reader.readAsText(file);
        reader.onload = function() {
            variableIs = this.result

            function sleep (time) {
                return new Promise((resolve) => setTimeout(resolve, time));
              }     

            function display(asd) {
                const usingSplit = asd.split(' ')

                lengthOf = usingSplit.length

                for (var i = 0;i < lengthOf;i++) {
                    sleep(1000).then(() => {
                        document.getElementById('test').innerHTML = usingSplit[i];
                    });
                }
            }
            display(variableIs);       
        }
    }   

}

getElement()

The HTML code is just this simple one :

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1 id="test">TEST</h1>
    <script src="test4.js"></script>

</body>
</html>

perj
  • 15
  • 1
  • 6
  • 1
    Your loop is not async, so 'sleep' is called for all elements in you for loop close to simultaneously. Your loop does not wait for the promise to be fulfilled. – NickG Sep 21 '22 at 15:20

1 Answers1

1

The problem is the var inside the for loop.
You should use let instead due to the way both work.

Read this post to understand their difference: What is the difference between "let" and "var"?

The way you're using the sleep function is not gonna work since they will execute at the same time. You can solve this by using async await.

function delay(ms = 0) {
  return new Promise(resolve => setTimeout(resolve, ms))
}

const inputFile = document.getElementById('files')
const test = document.getElementById('test')

function init() {
  inputFile.onchange = async function() {
    const file = this.files[0];
    
    const content = await file.text()

    const splitText = content.split(' ')

    for (let i = 0; i < splitText.length; i++) {
      test.innerHTML = splitText[i]

      // Here we are actually waiting in the for loop since this is an async function
      await delay(1000)
    }
  }
}

init()
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <h1 id="test">TEST</h1>
        <input id="files" type="file">
    </body>
</html>
Xion 14
  • 427
  • 2
  • 8