0

I am loading an external JSON file with $.ajax(), and I am puzzled as to why my error function will only execute a console.log, or alert, but nothing else? In my example, if the JSON is found, the screen turns blue. If the JSON is not found (i.e. I change the name of the test.js file to something that doesn't exist), the screen should turn red, but this isn't happening. What's wrong with my code?

$.ajax({
        url: 'test.js',
        dataType: 'json',
        timeout: 3000,
        success: function( data ) { success() },
        error: function( data ) { fail() }
      });



function success(){
    $("body").css("background", "blue");  //this works!
    console.log("success");               //this works!
}


function fail(){
    $("body").css("background", "red");   //this doesn't work :(
    console.log("fail");                  //this works!
}

Thanks,

Systematix Infotech
  • 2,345
  • 1
  • 14
  • 31
p1xelarchitect
  • 289
  • 1
  • 6
  • 19
  • So how is the ajax function not executing properly? – Popnoodles Jun 07 '14 at 03:35
  • the fail() function will correctly output to the console, but will not change the body background to red, per my code. why not? – p1xelarchitect Jun 07 '14 at 03:37
  • 1
    What makes you think that's anything to do with the ajax function? By all accounts that bit works fine; It calls success() on success and fail() on fail. – Popnoodles Jun 07 '14 at 03:39
  • 2
    The given code works in isolation http://jsfiddle.net/59U8V/ – Popnoodles Jun 07 '14 at 03:41
  • OK. Maybe it has nothing to do with my ajax() function... yes, it accesses the fail() function perfectly, as expected. BUT - Given my code above, why doesn't the screen turn red if test.js doesn't exist? – p1xelarchitect Jun 07 '14 at 03:43
  • Interesting! Your code works.. because you wrapped the ajax in a $(function(){}); ...It doesn't work without that. Wonder why... If you post that as an answer I'll accept it :) thanks! – p1xelarchitect Jun 07 '14 at 03:49
  • jQuery is sooo weird sometimes. It saves you like 3 lines of code in comparison to native js with XMLHttpRequest +the ie fallback but introduces all sorts of arbitrary weirdness. For example what's "dataType"? is it "responseType" or "overrideMimeType()"? What's success? Is it onreadystatechange with `readyState===4 && statusCode===200`? who knows? good thing no one ever has experiences unexpected behavior when reducing everything to single vague words. – Winchestro Jun 07 '14 at 03:53
  • Guess I'll cancel that jQuery tattoo I had planned... – p1xelarchitect Jun 07 '14 at 03:58
  • @p1xelarchitect don't get me wrong, jQuery is awesome, it's a brilliant piece of software if you know how exactly everything works it will just make you life that much more enjoyable. If you don't and just start out it obfuscates everything into unrecognizable and unpredictable buggy mess. – Winchestro Jun 07 '14 at 04:01
  • (in my above comment `statusCode` should be `status`, but whatever) – Winchestro Jun 07 '14 at 04:07
  • Based on popnoodles fiddle, I've made minor changes (my fiddle adds nothing to the question), just changes the success/fail to .done/.fail promise function - just for an example http://jsfiddle.net/59U8V/1/ – TimSPQR Jun 07 '14 at 04:22
  • @Winchestro I'm always open to learning better ways of doing things - but one must balance between perfection and speed. If I know how to achieve something in jQuery but am fuzzy on the details with the purist javascript method, I'll probably err on the side of speed and stick with jQuery :) – p1xelarchitect Jun 07 '14 at 05:00
  • @TimSPQR - thanks for your updated fiddle. Question for everyone... is "success" called if the JSON is found (i.e. exists)? Or only once it is fully downloaded into cache? – p1xelarchitect Jun 07 '14 at 05:01
  • 1
    "Success" is defined as an ajax event in which the server has finished the call, and the data are correct. Here is a nice page on ajax events - http://api.jquery.com/Ajax_Events/ – TimSPQR Jun 07 '14 at 05:16
  • @TimSPQR Ok then by your "definition" a server returning you a status code 304 is a success or a failure? What means "data are correct". if there is only one "correct" data, why are there 4 different response types on the XMLHttpRequest Object in the first place? The jQuery API doc doesn't tell you anything important. it literally tells you "This event is only called if the request was successful" which the vague term "success" already implies. – Winchestro Jun 07 '14 at 05:23
  • @p1xelarchitect I can partly understand your desire to get awesome results without investing time, just as I can understand why someone who just got his drivers licence wants to drive the fastest cars possible. You simply can't. You can only get speed quickly by sacrificing control. – Winchestro Jun 07 '14 at 05:29
  • From the link "no errors from the server, no errors with the data". And this page has a nice description of server responses for jQuery http://stackoverflow.com/questions/5173656/how-to-check-if-jquery-ajax-request-header-status-is-304-not-modified – TimSPQR Jun 07 '14 at 05:30
  • @Whinchestro are you suggesting i abandon $.ajax() and pursue XMLHttpRequest for this task instead? If so, how would you achieve the above code with your alternative? – p1xelarchitect Jun 07 '14 at 05:32
  • @TimSPQR The link you provided actually confirms what i've been saying in all aspects. If you want to have any control about anything beyond a very shallow, and vaguely defined oversimplified surface, you'll have to abandon jQuery. – Winchestro Jun 07 '14 at 05:35
  • @p1xelarchitect I'm suggesting you abandon jQuery entirely for a long time, learn how things actually work, and then only use it if you know exactly what happens behind the scenes. Then jQuery will transform from a race car driving around uncontrolled bumping into each corner, to a race car that will get get you from A to B in the shortest time possible. Because unless you know how to drive that race car, you will actually be *faster* if you walk. – Winchestro Jun 07 '14 at 05:40
  • @Winchestro I appreciate your feedback.. Side note: I've been working with javascript for over a decade. I'm very familiar with how it works, but never before have I needed to import JSON (or other). Now that I do, lucky me, I found you: a resource who is well versed in this arena. I'm looking for some guidance on either a) how to drive my Lamborghini without crashing, or b) if there is a safer vehicle, and if so, what is it. so far you've not given me any specific help other than telling me to avoid a) So - do you have some specific guidance? Or should I stick with plan A? – p1xelarchitect Jun 07 '14 at 05:51
  • @p1xelarchitect Oh ok then I'm terribly sorry, it was a mistake to make an assumption about your experience. You basically have 20x my experience in Javascript, but my frustration isn't without reasons. I've been working with Ajax techniques for a while, and it's frustratingly hard to find anything about it on the internet. 99% of all resources about that topic are about jQuery and as you just saw if you clicked the link to the API doc it's not telling anything useful, neither do most people using it. – Winchestro Jun 07 '14 at 05:59
  • *"Interesting! Your code works.. because you wrapped the ajax in a $(function(){}); ...It doesn't work without that. Wonder why..."* You wonder why? It's the **first** thing you're told about in the introduction to using jQuery. – Popnoodles Jun 08 '14 at 13:51

1 Answers1

1

If you were to write the above in pure js you'd need to specify almost the same parameters, just now you know specifically what happens and why it does or doesn't work because you can examine everything and it's not obscured by jQuery methods. note: the switch structure is my personal preference, most people do it with a (readyState === 4 && status === 200) but I always like to keep the ability to expand it to a more sophisticated error handling.

var xhr = new XMLHttpRequest();
xhr.responseType = "json";
xhr.timeout = 3000;
xhr.open("GET","test.js"); //method, url, async [default:true], username, password
xhr.onreadystatechange = function(){
    if(xhr.readyState === xhr.DONE){  
        switch(xhr.status){
           case:200  
               success(xhr); 
               break;
           default:
               failure(xhr);
               break;
        }
    }
}
xhr.send();

function success(request){
    document.body.style.background = "blue";
    console.log(request.status,request.statusText); //> 200 "OK"
}
function failure(request){
    document.body.style.background = "red";
    console.log(request.status,request.statusText); // reason for error
}

since it's not a jQuery answer and therefore totally off topic I know I'm going to get a ton of downvotes, but I'm ok with that. I'll just have to answer a bunch of other questions to make up for the rep loss.

Winchestro
  • 2,138
  • 14
  • 18
  • 1
    Thank you! I'm trying it out now. I agree that there is a strange paucity of information on the internet about how to do this without jQuery. – p1xelarchitect Jun 07 '14 at 07:11