-1

I'm trying to write a text game where word loads from external file, a bar draws in from the left and the word comes from the right, when they collide a life will be lost. I am wondering why all code has to be in the 2nd if statement when loading the file. Why can't you just not make the file management as a function?

      var wordNo, letters, lines, arrLetters;

      function getRandom(min, max) {
        return Math.trunc(Math.random() * (max - min) + min);
      }

      var txtFile = new XMLHttpRequest();
      txtFile.open("GET", "database.txt", true);
      txtFile.onreadystatechange = function () {
        if (txtFile.readyState === 4) {
          if (txtFile.status === 200) {
            allText = txtFile.responseText;
            lines = txtFile.responseText.split("\n");

            wordNo = getRandom(1, lines.length);
            letters = lines[wordNo];
            console.log(letters);

            arrLetters = "";
            arrLetters = letters.split("");
            arrLetters.pop();

            console.log(arrLetters);
          }
        }
      };
      txtFile.send(null);
Justin Taddei
  • 2,142
  • 1
  • 16
  • 30
Omninode
  • 13
  • 7
  • What do you mean by “make the file management as a function”? – Danny Dec 20 '20 at 22:29
  • It's not clear what you're asking. Perhaps if you showed an example of what you mean by _"make the file management as a function"_, it would be clearer – Phil Dec 20 '20 at 22:29
  • I mean that I would like to have everything from "var txtFile" to console.log(arrLetters) in a function that returns the "arrLetters" – Omninode Dec 20 '20 at 22:35
  • Does this answer your question? [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Phil Dec 20 '20 at 23:06

1 Answers1

1

If you're trying to convert the AJAX request into a function you can call and have the result returned, you could use a Promise.

Read more about Promises in JavaScript here

function getArrLetters() {
  return new Promise((resolve, reject) => {
    var wordNo, letters, lines, arrLetters

    function getRandom(min, max) {
      return Math.trunc(Math.random() * (max - min) + min)
    }

    var txtFile = new XMLHttpRequest()
    txtFile.open('GET', 'database.txt', true)
    txtFile.onreadystatechange = function () {
      if (txtFile.readyState === 4) {
        if (txtFile.status === 200) {
          allText = txtFile.responseText
          lines = txtFile.responseText.split('\n')

          wordNo = getRandom(1, lines.length)
          letters = lines[wordNo]
          console.log(letters)

          arrLetters = ''
          arrLetters = letters.split('')
          arrLetters.pop()

          resolve(arrLetters)
        }
      }
    }

    txtFile.onerror = reject

    txtFile.send(null)
  })
}

The modern way
If you don't need to support older browsers, or you're transpiling your code to ES5, you could write this a lot cleaner using ES6 syntax and the Fetch API.

const random = (min, max) => Math.trunc(Math.random() * (max - min) + min)

async function getArrLetters() {
  let allText = await fetch('database.txt').then((r) => r.text())
  let lines = allText.split('\n')

  let wordNum = random(1, lines.length)
  let letters = lines[wordNum]

  arrLetters = letters.split('')
  arrLetters.pop()

  return arrLetters
}

Usage (for either example):

getArrLetters().then(arrLetters => {
    // Use arrLetters here.
})

// Or from inside an async function:

async function yourFunction() {
    var arrLetters = await getArrLetters()
}

You cannot directly return the result from a function because a network request is inheritly asynchronous.

Justin Taddei
  • 2,142
  • 1
  • 16
  • 30