0

I have a code like the one stated below, please how do I get the value for (getData), using a code like:

var instanceArray = myGraph.getInstances(component)

I was thinking myGraph.getInstances(component).getData will do it, but it failed

this.getInstances = function(component) {
    var getData = {};
        $.ajax({
            url: "/rpc/alerts2/commonObj_rpc.cfc?method=getInstances",
            data: {"component":component},
            type: "POST",
            async: true,
            success: function(data) {
                getData = $.parseJSON(data);
                console.log("hey");
                var $render_component_instance = $("#instances").empty();
                $("#instances").append($("<option />").val("all").text("All Instances (Summed)"));
                $.each(getData, function (cIndex, cItem){
                    var $instance = $("<option />").val(cItem.si_instance).text(cItem.si_label.toUpperCase());
                    $render_component_instance.append($instance);
                })
                $("#instances").multiselect("refresh");
            }
        });
};`
Cerbrus
  • 70,800
  • 18
  • 132
  • 147
deetu
  • 79
  • 7

1 Answers1

2

You can't, the get is asynchronous. getInstances returns before the GET completes, so it's impossible for getInstances to return the data. (See further note below.)

You have (at least) three options:

  1. Use a callback

  2. Return a blank object that will get populated later, and have the code that needs it poll it periodically

  3. Use a synchronous get (not a good idea)

1. Use a callback

What you can do instead is accept a callback, and then call it when the data arrives:

this.getInstances = function(component, callback) {

    $.ajax({
        url: "/rpc/alerts2/commonObj_rpc.cfc?method=getInstances",
        data: {"component":component},
        type: "POST",
        async: true,
        success: function(data) {
            var getData = $.parseJSON(data);
            console.log("hey");
            var $render_component_instance = $("#instances").empty();
            $("#instances").append($("<option />").val("all").text("All Instances (Summed)"));
            $.each(getData, function (cIndex, cItem){
                var $instance = $("<option />").val(cItem.si_instance).text(cItem.si_label.toUpperCase());
                $render_component_instance.append($instance);
            })
            $("#instances").multiselect("refresh");
            callback(getData);
        }
    });
};

And call it like this:

myGraph.getInstances(component, function(data) {
    // Use the data here
});

2. Return a blank object that will get populated later

Alternately, you can return an object which will be blank to start with, but which you'll add the data to as a property later. This may be closest to what you were looking for, from your comments below. Basically, there's no way to access a function's local variables from outside the function, but you can return an object and then add a property to it later.

this.getInstances = function(component) {

    var obj = {};

    $.ajax({
        url: "/rpc/alerts2/commonObj_rpc.cfc?method=getInstances",
        data: {"component":component},
        type: "POST",
        async: false,    // <==== Note the change
        success: function(data) {
            var getData = $.parseJSON(data);
            console.log("hey");
            var $render_component_instance = $("#instances").empty();
            $("#instances").append($("<option />").val("all").text("All Instances (Summed)"));
            $.each(getData, function (cIndex, cItem){
                var $instance = $("<option />").val(cItem.si_instance).text(cItem.si_label.toUpperCase());
                $render_component_instance.append($instance);
            })
            $("#instances").multiselect("refresh");

            // Make the data available on the object
            obj.getData = getData;
        }
    });

    return obj; // Will be empty when we return it
};

And call it like this:

var obj = myGraph.getInstances(component);

// ...later...
if (obj.getData) {
    // We have the data, use it
}
else {
    // We still don't have the data
}

3. Use a synchronous get

I do not recommend this, but you could make the call synchronous. Note that synchronous ajax requests will go away in a future version of jQuery. But just for completeness:

this.getInstances = function(component) {

    var getData;    
    $.ajax({
        url: "/rpc/alerts2/commonObj_rpc.cfc?method=getInstances",
        data: {"component":component},
        type: "POST",
        async: false,    // <==== Note the change
        success: function(data) {
            var getData = $.parseJSON(data);
            console.log("hey");
            var $render_component_instance = $("#instances").empty();
            $("#instances").append($("<option />").val("all").text("All Instances (Summed)"));
            $.each(getData, function (cIndex, cItem){
                var $instance = $("<option />").val(cItem.si_instance).text(cItem.si_label.toUpperCase());
                $render_component_instance.append($instance);
            })
            $("#instances").multiselect("refresh");
        }
    });

    return getData;
};

And call it like this:

var getData = myGraph.getInstances(component);

But again, I don't advocate that. Synchronous ajax calls lock up the UI of the browser, leading to a bad user experience.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Can you explain the call please – deetu Dec 05 '12 at 10:54
  • @deetu: Happy to, but what specifically...? – T.J. Crowder Dec 05 '12 at 10:55
  • i know i can easy get the data using synchronous, but im trying to just retrieve the getdata, so the instance doesnt to run the lines after it – deetu Dec 05 '12 at 10:58
  • @deetu: I'm sorry, I don't understand that sentence. What does "...so the instance doesn't to run the lines after it..." mean? – T.J. Crowder Dec 05 '12 at 10:59
  • i just need the data from getData, thats all – deetu Dec 05 '12 at 10:59
  • @deetu: First off, sorry, I messed up my initial two examples (I set the wrong one of them to be `async: false`!). So I've fixed that. I also added a new example (#2) which may be what you're looking for. Basically, there's no way to access a local variable from outside a function, but there are alternatives that do something similar. – T.J. Crowder Dec 05 '12 at 11:04