问题描述:

I am trying to return an object through the _fail callback (Yes, this is meant to run the fail callback), but failSeries is returning as undefined in the console. Any ideas?

var ChartModule = (function ( $, HC, HA, window, undefined) {

//Define public object

var pub = {};

//Private methods

var _getChartData = function (URL, sendData) {

var xhrObject = $.ajax({

url: URL,

type: "POST",

data: sendData,

success: function (result) { },

error: function (jqXHR, textStatus, errorThrown) {}

});

_chartDataResponse(xhrObject);

};

var _done = function (data, textStatus, jqXHR) {

var seriesObject = $.parseJSON(data);

return seriesObject;

};

var _fail = function(){

var failSeries = [];

var seriesData = {

data: [{y: 7, id: 'pointAssets', color: '#5c8fb8'}, {y:10, id: 'pointLiabilities', color: '#bb77b5'}, {y:-3, id: 'pointResult', color: '#cc5971'}],

};

failSeries.push(seriesData);

return failSeries;

};

var _chartDataResponse = function(xhrObject){

xhrObject.then(_done, _fail);

};

var _renderChart = function(renderTo, seriesObject){

console.log("Chart will be rendered to: '" + renderTo + "'");

console.log(seriesObject);

};

//Public methods

pub.getChartData = _getChartData;

pub.renderChart = _renderChart;

return pub;

})(jQuery, Highcharts, HighchartsAdapter, window, undefined);

I am then using my module in the following way in an attempt to view the object that has been returned by either the success or fail callabcks:

$(function(){

var x = ChartModule.getChartData("someURL", {test: "test"});

ChartModule.renderChart("breakdown-chart", x);

});

网友答案:

With a slightly better understanding (and use) of $.ajax(), ChartModule will reduce down to far fewer public methods. In particular :

  • be aware that $ajax() returns a promise, which can (and should) itself be returned by getChartData() thus allowing consequential action on success/failure to be taken externally.
  • with appropriare low level error handling in a chained then() inside getChartData() you can make an error message AND the fake seriesData available where ChartModule.getChartData() is called.
var ChartModule = (function ( $, HC, HA, window, undefined) {
    //Private members
    var fakeSeriesData = { data: [{y: 7, id: 'pointAssets', color: '#5c8fb8'}, {y:10, id: 'pointLiabilities', color: '#bb77b5'}, {y:-3, id: 'pointResult', color: '#cc5971'}] };
    function _getChartData(URL, sendData) {
        return $.ajax({
            url: URL,
            type: "POST",
            data: sendData,
            dataType: 'json'
        }).then(null, function (jqXHR, textStatus, errorThrown) {
            var e = new Error(textStatus);
            e.seriesData = getFakeSeriesData();
            return e; //return an augmented Error object.
        });
    }
    function _renderChart(renderTo, seriesObject) {
        console.log("Chart will be rendered to: '" + renderTo + "'");
        console.dir(seriesObject);
        return ...;//something meaningful
    }
    function _getFakeSeriesData() {
        return $.extend({}, fakeSeriesData);
    }
    //Public methods
    return {
        getChartData: _getChartData,
        renderChart: _renderChart,
        getFakeSeriesData: _getFakeSeriesData//make the fake series data directly availalbe.
    };
})(jQuery, Highcharts, HighchartsAdapter, window, undefined);

This strategy will allow control to be execised where ChartModule.getChartData() is called, with no assumptions about what actions might be taken on success or failure of the AJAX other than, on error, to make the fake seriesData available with no knowledge of how/whether it will be used.

Call as follows :

$(function() {
    ChartModule.getChartData("someURL", {
        test: "test"
    }).done(function(seriesData) {
        ChartModule.renderChart("breakdown-chart", seriesData);
    }).fail(function(error) {
        if(error.seriesData) {
            console.log(error.message);
            ChartModule.renderChart("breakdown-chart", error.seriesData);
        } else {
            console.error(error);
            //some othe couse of action
        }
    });
});

At some other point in your code, you could call ChartModule.getChartData() and take completely different actions in response. You could, on error, even inject some other fake seriesData that is, for whatever reason, more appropriate than the default.

网友答案:

I am trying to return an object through the _fail callback (Yes, this is meant to run the fail callback). I am then using my module in the following way in an attempt to view the object that has been returned by either the success or fail callabcks:

No. You can't do that. Callbacks don't return anything. See How to return the response from an Ajax call?.

but failSeries is returning as undefined in the console.

Because failSeries is a variable that is local to your _fail function, and gets returned to nothing from it.

Any ideas?

Return the promise. And then wait until it resolves before calling renderChart (from a callback).

var ChartModule = (function( $, HC, HA, window, undefined) {

    function getChartData(URL, sendData) {
        return $.ajax({
            url: URL,
            type: "POST",
            data: sendData
        }).then(done, fail);
    }

    function done(data, textStatus, jqXHR) {
        return $.parseJSON(data);
    }

    function fail() {
        // ignore errors, continue with fake data
        return new $.Deferred().resolve([
            {data: [{y: 7, id: 'pointAssets', color: '#5c8fb8'}, {y:10, id: 'pointLiabilities', color: '#bb77b5'}, {y:-3, id: 'pointResult', color: '#cc5971'}]}
        ]);
    }

    function renderChart(renderTo, seriesObject){
        console.log("Chart will be rendered to: '" + renderTo + "'");
        console.log(seriesObject);
    }

    return {
        getChartData: getChartData,
        renderChart: renderChart
    };

})(jQuery, Highcharts, HighchartsAdapter, window, undefined);

$(function(){
    ChartModule.getChartData("someURL", {test: "test"}).then(function(x) {
        ChartModule.renderChart("breakdown-chart", x);
    });
});
相关阅读:
Top