3

I am writing an backbone js web app on top of an JSON server that returns JSON responses in JSend specification format.

Here are a few examples of that format:

GET /posts

{
 "status": "success",
 "data": {
   "posts" [
     {"id": 1, "title": "A blog post"}, 
     {"id": 2, "title": "another blog post"}
   ]
 }
}

POST /posts

{
  "status": "fail",
  "data": {
    "title": "required"
  }
}

By default the "error" event in $.ajax gets triggered by http codes, but since the JSend specification format does not use HTTP codes at all, I have to rewrite the $.ajax error handler.

The way it works by default (http codes):

$.ajax({
  error: function() {
    // Do your job here.
  },
  success: function() {
    // Do your job here.
  }
});

How can I rewrite the $.ajax error handler that it gets triggered when parsed the body and if the "status" property is "fail" or "error"?

5
  • You could use the dataFilter callback to invalidate the json if it's an error, however you would then lose any error messages that get returned and add complexity to your code. You're better off detecting if it's an error within the success handler instead. Commented Jan 21, 2013 at 15:53
  • What JSON Server are you using, can't you just make it sending proper HTTP status codes?? I don't think that it would be forbidden to use JSend AND HTTP codes to ensure correct behavior. Commented Jan 21, 2013 at 15:55
  • @ohcibi I don't like HTTP codes, everywhere I look everyone has a different opinion about codes, so I don't want to use HTTP codes at all. Commented Jan 21, 2013 at 15:56
  • @onlineracoon Hm, I don't share the same experience; but in this case the answer to your question if there is no other way to do it, is clear (you should get an idea what HTTP status codes are good for if you think further about the problem 8-)). Commented Jan 21, 2013 at 15:58
  • 1
    @onlineracoon is your goal to avoid having if (json.status == 'fail') visible in your code at all? Commented Jan 21, 2013 at 16:03

2 Answers 2

4

As counter-intuitive as it seems, you will have to put it in the success function. Simply check the value yourself:

$.ajax({
  error: function() {
    // Handle http codes here
  },
  success: function(data) {

    if(data.status == "fail"){
      // Handle failure here
    } else {
      // success, do your thing
    }

  }
});
Sign up to request clarification or add additional context in comments.

4 Comments

Together with deferred objects, the error case could be handled transparently.
This would be my last resort, is there no other way to do this?
No. you can make it less obvious that you are doing this by hiding it behind a custom method, however in the end this is what you would be doing.
@FelixKling Perhaps you could elaborate in an answer? I would be interested to see what you had in mind. I have to be honest and say that I don't often bother with deferred aside from waiting on multiple requests.
1

To keep the things DRY you can use something like this:

function JSendHandler(success, fail) {
    if (typeof success !== 'function' || typeof fail !== 'function') {
        throw 'Please, provide valid handlers!';
    }
    this.success = success;
    this.fail = fail;
}

JSendHandler.prototype.getHandler = function () {
    return function (result) {
        if (result.status === 'fail') {
            this.fail.call(this, arguments);
        } else {
            this.success.call(this, arguments);
        }
    }
};

function success() { console.log('Success'); }
function error() { console.log('Fail!'); }

var handler = new JSendHandler(success, error);

$.ajax({
  error: error,
  success: handler.getHandler()
});

1 Comment

Slight correction, when creating the new JSendHandler the 2nd parameter should be error.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.