0

I'm trying to write some java script code that will (if the file exists) add its content to the web page, if it doesn't exist then it will check if the next file exists. I currently have it displaying the data if the file exists, however throws

GET http://localhost:8080/temp1.xml 404 (Not Found)
xmlhttp.onreadystatechange @ friends.html:56
XMLHttpRequest.send (async)
(anonymous) @ friends.html:95

if the file doesn't exist.

I've already tried adding i try catch around different parts but none of them seem to stop the error from occurring. ive also been trying to find a decent guide on how to handle not found errors but cant seem to find one that would work in my case.

this is the code I have without the try excepts.

xmlhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        JSObj = JSON.parse(this.responseText);
        console.log(JSObj.friends.length);
        for (i = 0; i < JSObj.friends.length; i++) {
            name = JSObj.friends[i].name;
            xhttp1.open("GET", "temp"+ i +".xml", true);
            xhttp1.send();
        };
    };
};

this is the code I have with the try excepts

xmlhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        JSObj = JSON.parse(this.responseText);
        console.log(JSObj.friends.length);
        for (i = 0; i < JSObj.friends.length; i++) {
            name = JSObj.friends[i].name;
            try{
                xhttp1.open("GET", "temp"+ i +".xml", true);
                xhttp1.send();
           }catch(err){
                console.log(err);
           };
        };
    };
};

the output I'm getting is a blank page due to the error stopping the code I have working from working which is when the error above is output. I expect that it would just skip that file and go onto the next one.

  • Lots of issues here. For starters, you need a `new XMLHttpRequest` created for every request so each request fires it's own `onreadystatechange`. Then you are not using `let` in for loop which will present the problem of accessing correct `i` when looped requests complete. See [JavaScript closure inside loops – simple practical example](https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example). Then you have issue of handling the synchronicity of multiple requests in a loop which will require using promises – charlietfl Apr 11 '19 at 15:31
  • I have all that, I'm just showing the snippet that is giving me the error because the code is quite large – Stanley Roy Chilton Apr 11 '19 at 15:37
  • No...you don't have that. Your loop uses the same request object `xhttp1` each time. And there is no `onreadystatechange` shown for the requests inside the loop. And the lack of closure in the for loop is really important. Understand the link I provided. Everyone learning javascript runs into it – charlietfl Apr 11 '19 at 15:38
  • okay thank you, ill have a more indepth read of it – Stanley Roy Chilton Apr 11 '19 at 15:41
  • One last thing... will need to check other status than 200 and do something different when it is 404, 500 etc – charlietfl Apr 11 '19 at 15:55

1 Answers1

0

That's not the way XMLHttpRequest works. Perceive the difference you're treating the call that run that code and what you're expecting open() method to do. First you have asynchronously made a call to a URL you have not mentioned. When this process returned it called the onreadystatechange event which runned the code you posted in the question. Then you expect open() method to function differently and use a try/catch. See the difference ? See that you have setted the async parameter to true. So you are opening a whole new call on another object called xmlhttp1. With this 2nd call you create another XMLHttpRequest request that should be addressed by another onreadystatechange method to process it.

You can read more on using XMLHttpRequest here:

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest

More or less like this :

NOT TESTED PSEUDO-CODE

xmlhttp1 = new XMLHttpRequest();
xmlhttp1.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        // whatever you want to do with the call to   
        // xhttp1.open("GET", "temp"+ i +".xml", true);
    } 
}

xmlhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        JSObj = JSON.parse(this.responseText);
        console.log(JSObj.friends.length);
        for (i = 0; i < JSObj.friends.length; i++) {
            name = JSObj.friends[i].name;
            xhttp1.open("GET", "temp"+ i +".xml", true);
            xhttp1.send();
        };
    };
};

Please adapt this code. It's just to illustrate what I mean and probably will not work this way.

Nelson Teixeira
  • 6,297
  • 5
  • 36
  • 73
  • 1
    The pseudo code won't work by using same `xhttp1` object for each request and needs a new request and onreadystatechange – charlietfl Apr 11 '19 at 15:45
  • Still conceptually wrong. A `new XMLHttpRequest` will not be created for each request in loop – charlietfl Apr 11 '19 at 15:52
  • For OP... think along lines of when need to make a request need to create a new request object for that individual request – charlietfl Apr 11 '19 at 15:58
  • for (i = 0; i < JSObj.friends.length; i++) { xmlhttp1 = new XMLHttpRequest(); name = JSObj.friends[i].name; something like this right? obviously removed rest of code because of the character limit – Stanley Roy Chilton Apr 11 '19 at 16:02
  • @StanleyRoyChilton need to get out of habit of not using variable declarations like var, let, const. Otherwise they are global variables and can collide – charlietfl Apr 11 '19 at 17:04