0

I'm a beginner in JavaScript and tried making a simple Anagram generator that, after all the possible permutations are generated, checks if the words I just generated are valid Italian words. My problem is that when I try to convert the response from a "dictionary" file I found online into an array (don't know if that's necessary, but wanted to try this way), the Google Chrome developer console gives me the below error:

index.html:24 Uncaught TypeError: Cannot read property 'split' of undefined at index.html:24

I'm really confused, because if I copy and paste the 24th line from my code into the console (changing the variable name) and then execute it, it works just fine.

Am I missing something? I really don't know how to solve that.

Here's the code:

let dict = resp.responseText.split("\n"); // <- LINE 24
let words = [];
let generate = function(k, A) {
  if (k == 1) words.push(A.join(""));
  else generate(k - 1, A);

  for (let i = 0; i < k - 1; i++) {
    if (k & 0) {
      swap(A, i, k - 1);
    } else {
      swap(A, 0, k - 1);
    }
    generate(k - 1, A);
  }
}

let anagram = function() {
  let chars = document.getElementById("w").value.split("");
  let len = chars.length;
  if (len >= 6) alert("Usa meno di 6 caratteri")
  else generate(chars.length, chars);


  //let p = document.getElementById("output");
  //p.innerHTML = "";

}

let swap = function(arrStr, a, b) {
  let tmpVal = arrStr[a];
  arrStr[a] = arrStr[b];
  arrStr[b] = tmpVal;
  return arrStr;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
  let resp = jQuery.ajax({
    url: 'https://raw.githubusercontent.com/napolux/paroleitaliane/master/paroleitaliane/660000_parole_italiane.txt',
  });
</script>


<input type="text" id="w" onchange="anagram();" />
<br>
<p id="output"></p>
Kate Orlova
  • 3,225
  • 5
  • 11
  • 35
DDC
  • 61
  • 4
  • `resp` will return a Promise/jQuery Deferred (basically a jQuery version of a Promise), it won't be a response. You need to either use the Promise/Deferred API to interact with the value once it's ready or you need to pass a callback to the `$.ajax` function which would still be executed when the data is avaiable – VLAZ Feb 02 '20 at 17:52

5 Answers5

1

jQuery.ajax is an async function you have to handle it like this.

jQuery.ajax({
  url:
    "https://raw.githubusercontent.com/napolux/paroleitaliane/master/paroleitaliane/660000_parole_italiane.txt",
  success: function(resp) {
    let dict = resp.responseText.split("\n"); // <- LINE 24
    console.log(dict);
  }
});

Sohail Ashraf
  • 10,078
  • 2
  • 26
  • 42
1

Your problem is clear. This code is asynchronous:

let resp = jQuery.ajax({
            url: 'https://raw.githubusercontent.com/napolux/paroleitaliane/master/paroleitaliane/660000_parole_italiane.txt',
        });

And the data in your resp variable appears once the request is success.

However, your code

let dict = resp.responseText.split("\n");

works before the request is fulfilled and thus you get undefined

In order to fix it you should move your code inside your jquery response handler like this

jQuery.ajax({
        url: 'https://raw.githubusercontent.com/napolux/paroleitaliane/master/paroleitaliane/660000_parole_italiane.txt',
        success: function(response) {
          let dict = response.split("\n");
          ... // All your latter code goes here
        },
        error: function (error) {
           // Also a good practice to add some error handling
        }
      });

Your problem is not reproduced in console because before you open the console and trying to reproduce the issue the request usually fulfills and thus you hav all the required data

Please, read some your problem-related articles:

Sergey Mell
  • 7,780
  • 1
  • 26
  • 50
  • Thanks for the reply, however i get the same error... but i managed to fix it! Thanks a lot. I just wrote response.split("\n"); and it worked. Thank you very much!! – DDC Feb 02 '20 at 18:14
  • Yeah, you're right. My fault. Let me update the answer – Sergey Mell Feb 02 '20 at 18:42
0

You should move the Ajax call to your code script tag to be able to use the response here how it should be (note that it will take time to process) since its asynchronies issue as mentioned by other answers, here is a running code:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <title>Document</title>
</head>

<body>

    <input type="text" id="w" onchange="anagram();" />
    <br>
    <p id="output"></p>

    <script>
     jQuery.ajax({
            url: 'https://raw.githubusercontent.com/napolux/paroleitaliane/master/paroleitaliane/660000_parole_italiane.txt',
        }).done(function( resp ) {
        console.log(resp);
    let dict = resp.split("\n"); // <- LINE 24
        let words = [];
        let generate = function (k, A) {
            if (k == 1) words.push(A.join(""));
            else generate(k - 1, A);

            for (let i = 0; i < k - 1; i++) {
                if (k & 0) {
                    swap(A, i, k - 1);
                } else {
                    swap(A, 0, k - 1);
                }
                generate(k - 1, A);
            }
        }

        let anagram = function () {
            let chars = document.getElementById("w").value.split("");
            let len = chars.length;
            if (len >= 6) alert("Usa meno di 6 caratteri")
            else generate(chars.length, chars);


            //let p = document.getElementById("output");
            //p.innerHTML = "";

        }

        let swap = function (arrStr, a, b) {
            let tmpVal = arrStr[a];
            arrStr[a] = arrStr[b];
            arrStr[b] = tmpVal;
            return arrStr;
        }
  });
        
    </script>
</body>

</html>
ROOT
  • 11,363
  • 5
  • 30
  • 45
0

Async / Await method:

 (async function(){
   let resp = await jQuery.ajax({
        url: 'https://raw.githubusercontent.com/napolux/paroleitaliane/master/paroleitaliane/660000_parole_italiane.txt',
    });
  let dict = resp.responseText.split("\n"); // <- LINE 24
    let words = [];
    let generate = function (k, A) {
        if (k == 1) words.push(A.join(""));
        else generate(k - 1, A);

        for (let i = 0; i < k - 1; i++) {
            if (k & 0) {
                swap(A, i, k - 1);
            } else {
                swap(A, 0, k - 1);
            }
            generate(k - 1, A);
        }
    }

    let anagram = function () {
        let chars = document.getElementById("w").value.split("");
        let len = chars.length;
        if (len >= 6) alert("Usa meno di 6 caratteri")
        else generate(chars.length, chars);


        //let p = document.getElementById("output");
        //p.innerHTML = "";

    }

    let swap = function (arrStr, a, b) {
        let tmpVal = arrStr[a];
        arrStr[a] = arrStr[b];
        arrStr[b] = tmpVal;
        return arrStr;
    }
  })()
bill.gates
  • 14,145
  • 3
  • 19
  • 47
0

jQuery.ajax() function does not return response object but jqXHR object. So if you want get result of ajax call, you must give callback function which is called after success of ajax call.

jQuery.ajax(url, function(response) {
    // do split here.
    let dict = response.split( "\n");
    //...
});
Joe
  • 132
  • 5