Danie A
Danie A

Reputation: 821

Invoke callback method

I'm trying to make a nice AJAX interface, loosely adapted to Todd Motto's Atomic.JS (http://toddmotto.com/writing-a-standalone-ajax-xhr-javascript-micro-library/). My adaption isn't working, however. The problem: when using the function like so

ajax.post(url, data)
    .success(function(x) {
        console.log('success',x);
    })
    .error(function(x) {
        console.log('error',x);
    });

The AJAX function can't 'reach' the error method, while the success behaves perfectly. When I only write the error function when it's called upon it does work perfectly, though. E.g. like so:

ajax.post(url, data)
    .error(function(x) {
        console.log('error', x);
    });

Here's my AJAX method

var ajax = (function() {

    var parse = function(req) {
        var result;
        try {
            result = JSON.parse(req.responseText);
        } catch (e) {
            result = req.responseText;
        }
        return [result, req];
    };

    var xhr = function(type, url, data) {
        var methods = {
            success: function() {},
            error: function() {}
        };
        var XHR = XMLHttpRequest || ActiveXObject;
        var request = new XHR('MSXML2.XMLHTTP.3.0');
        request.open(type, url, true);
        request.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
        request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
        request.onreadystatechange = function() {
            if (request.readyState === 4) {
                if (request.status === 200) {
                    methods.success.apply(methods, parse(request));
                } else {
                    methods.error.apply(methods, parse(request));
                }
            }
        };
        request.send(data);
        return {
            success: function(callback) {
                methods.success = callback;
                return methods;
            },
            error: function(callback) {
                methods.error = callback;
                return methods;
            }
        };
    };

    return {
        get: function(url) {
            return xhr('GET', url);
        },
        post: function(url, data) {
            return xhr('POST', url, data);
        }
    };

})();

I see that Todd Motto uses a Factory method, which I'm not familiar with. Please help me reach my .error!

Upvotes: 1

Views: 1448

Answers (1)

Amberlamps
Amberlamps

Reputation: 40448

Well, the problem is when you executing the success function, you only set the success callback. The error callback is overwritten by the empty placeholder function. Therefore when you are setting the error callback by executing the object´s error function, you are not calling your desired function, but the empty function.

Try this:

var ajax = (function() {

    var parse = function(req) {
        var result;
        try {
            result = JSON.parse(req.responseText);
        } catch (e) {
            result = req.responseText;
        }
        return [result, req];
    };

    var xhr = function(type, url, data) {
        var methods = {
            success: function(callback) {
                this.success = callback;
                return this;
            },
            error: function(callback) {
                this.error = callback;
                return this;
            }
        };
        var XHR = XMLHttpRequest || ActiveXObject;
        var request = new XHR('MSXML2.XMLHTTP.3.0');
        request.open(type, url, true);
        request.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
        request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
        request.onreadystatechange = function() {
            if (request.readyState === 4) {
                if (request.status === 200) {
                    methods.success.apply(methods, parse(request));
                } else {
                    methods.error.apply(methods, parse(request));
                }
            }
        };
        request.send(data);
        return methods;
    };

    return {
        get: function(url) {
            return xhr('GET', url);
        },
        post: function(url, data) {
            return xhr('POST', url, data);
        }
    };

})();

Upvotes: 1

Related Questions