1

I have this code:

$.post(Routing.generate('parMarcaModelo'), {
    "marcaId": currBranch,
    "modeloId": currModel,
    "marcaNombre": currBranchName,
    "modeloNombre": currModelName
}, 'json').done(function (data, textStatus, jqXHR) {
    // do something here
}).fail(function (jqXHR, textStatus, errorThrown) {
    // Catch error from server and logs to console
    var err = eval("(" + jqXHR.responseText + ")");
    colose.log('Error', err.Message, 20000);

    return false;
});

The server side returns a JSON like this one:

{
   "success":false,
   "error":"El par Marca2-Modelo1 ya existe. Por favor escoja otra combinaci\u00f3n.",
}

But also returns a 400 code so Ajax call will go through .fail() callback insted of .done(). Having this information, how I can catch the error key from the JSON in the .fail() to show to users?

I have found this code:

$.get('http://localhost/api').then(function(res) {
    var filter $.Deferred()

    if (res.success) {
        filter.resolve(res.data)
    } else {
        filter.reject(res.error)
    }

    return filter.promise()
}).done(function(data) {
    console.log('Name:',  data.name) // Outputs: Foo
}).fail(function(error) {
    console.log('Error:', error) // Outputs: Something bad happened.
})

On this topic at SO but does not know if is right and also if will affect my code in someway.

Any help or advice?

Community
  • 1
  • 1
ReynierPM
  • 17,594
  • 53
  • 193
  • 363
  • If you get JSON you are in done() method – Benjamin Poignant Dec 03 '14 at 17:31
  • 1
    If the message is at `err.error`, why are you accessing `err.Message` instead? And why are you using `eval()` to parse your JSON? –  Dec 03 '14 at 17:34
  • ...and what do you mean by "catch" the `error` key? Are you throwing an error, or was this just an unfortunate use of the word `catch`, which has very specific meaning? –  Dec 03 '14 at 17:36
  • @squint I get that code from somewhere and is untested is just curious to me how it should work in order to modify and fit to my environment, should be `err.error` as you say? And for the `catch` I mean when any fails on the server side I send a `400` response to the Ajax request and also sends as a Json the generic message for the application, but I'm pretty sure that will be errors from the Ajax,jQuery, jqXHR side, I'm right? I need to catch all of them, the ones from JSON coming from 400 response and the ones from jqXHR, why? – ReynierPM Dec 03 '14 at 17:59
  • 1
    If I understand correctly, a clearer title might be something like "How to read a property from a JSON response when the HTTP response has a failure code?" – apsillers Dec 03 '14 at 18:01
  • @apsillers have sense, modifying right now – ReynierPM Dec 03 '14 at 18:01

1 Answers1

0

You are sending in 'json' as the success callback function to $.post().

This is the correct function signature: jQuery.post( url [, data ] [, success ] [, dataType ] )


Clarification

This code will work, since it passes in an empty function in place of the 'success'.

$.post('rest.php', {data : 'data'}, function(){},'json').done(
function (data, textStatus, jqXHR) {
    // do something here
}).fail(function (jqXHR, textStatus, errorThrown) {
    // Catch error from server and logs to console
    console.log('Error', jqXHR.responseJSON, 20000);

    return false;
});

However, this code will not:

$.post('rest.php', {data : 'data'}, 'json').done(
function (data, textStatus, jqXHR) {
    // do something here
}).fail(function (jqXHR, textStatus, errorThrown) {
    // Catch error from server and logs to console
    console.log('Error', jqXHR.responseJSON, 20000);

    return false;
});

For proof, look at line 781-798 in the jQuery source code. If the data parameter is a function, e.g. the success callback, the items will get shifted. However, since this is not the case, every parameter will be put in by the position they appear in the function.

In the second version, Ajax.succees will be set to the string 'json' and the Ajax.dataType is set to undefined. The jqXHR.responseJSON of that version will return a undefined, since it's not parsed as JSON.

The first version, however, returns a JSON object.


Also, you wrote colose.log instead of console.log in your code. That might be why couldn't get the data.

bvx89
  • 868
  • 5
  • 12
  • `[, ...]` means optional. –  Dec 03 '14 at 17:38
  • `return false;` is useless – epascarello Dec 03 '14 at 17:54
  • So this is the way I should go? @epascarello why? because the callback goes through `.fail()` and it's a fail itself? – ReynierPM Dec 03 '14 at 18:00
  • Why? because you can not return from an asynchronous method. – epascarello Dec 03 '14 at 18:02
  • @epascarello didn't know that one – ReynierPM Dec 03 '14 at 18:03
  • bvx89: You're just not understanding. Your clarification with the empty function is completely unnecessary because those arguments ***are optional***. Any one (or all) of the optional arguments can be excluded. Nothing needs to be put in its place. –  Dec 03 '14 at 21:09
  • 1
    @squint I edited my answer with the source code to explain what I meant. Others: I'd rather use the `$ajax` function in jQuery to create this functionality in a cleaner way, but I was trying not to alter the original code too much. That's why I didn't remove the `return false;` as well, which I know is useless. – bvx89 Dec 04 '14 at 01:44