6

Continuing with JQuery - Storing ajax response into global variable

Accepted solution somehow does not work for me.

$(document).ready(function() {
    var dataStore = (function(){
        var xml;

        $.ajax({
          type: "GET",
          url: "/?do=getcontentadm1n&category=homepage",
          dataType: "json",
          success : function(data) {
                        xml = data.html;
                alert(xml); // WORKS
                    }
        });

        return {getXml : function()
        {
            if (xml) return xml;
        }};
    })();

    var somevar = dataStore.getXml();

    alert(somevar); // UNDEFINED
});

Is there other solution?

Thanks.

Community
  • 1
  • 1
Alex G
  • 3,048
  • 10
  • 39
  • 78

5 Answers5

11

It's empty because by the time getXml is called, the ajax request has not completed, remember ajax is asynchronous. One way to get around it is to force it to be synchronous:

       $.ajax({
          async: false,
          type: "GET",
          url: "/?do=getcontentadm1n&category=homepage",
          dataType: "json",
          success : function(data) {
                        xml = data.html;
                alert(xml); // WORKS
                    }
        });

Responding to comment:

I want perform AJAX onclick, then store data.html for other mouse events

var dataStore = (function(){
    var html;
    function load(){
           $.ajax({
              async: false,
              type: "GET",
              url: "/?do=getcontentadm1n&category=homepage",
              dataType: "json",
              success : function(data) { html = data.html; }
            });
    }
    return {
        load : function() { 
            if(html) return;
            load();
        },
        getHtml: function(){
             if(!html) load();
             return html;
        }
    }
})();

$(element1).click(function(){
    dataStore.load();
});

$(element2).click(function(){
    var html = dataStore.getHtml();
    // use html
});
driangle
  • 11,601
  • 5
  • 47
  • 54
  • Sure enough. How about avoiding function in variable? – Alex G Feb 07 '12 at 04:29
  • i don't understand your question, can you be more specific? – driangle Feb 07 '12 at 04:30
  • Without this "var dataStore = (function(){". I want perform AJAX onclick, then store data.html for other mouse events. – Alex G Feb 07 '12 at 04:36
  • that's kind of outside the scope of your question, i would answer it here but it would make my answer irrelevant to the question. Basically you can do `$(element).click(loadDataUsingAjax);` where that function will load the data using the code I posted and then store it in some variable. – driangle Feb 07 '12 at 04:39
  • $(element1).click(loadDataUsingAjax storeinvar); $(element2).click(getstoredvar); – Alex G Feb 07 '12 at 04:45
2

The ajax call is async. It probably hasnt finished running when you call:

var somevar = dataStore.getXml();
ozczecho
  • 8,649
  • 8
  • 36
  • 42
1

Alright this is my first Reply but here it goes.

I've been bashing my head against this issue myself and learned this.

When you define a variable outside a function, it is automaticly added to the 'window' object.

so if we do this:

    var myValue;
    function setValue()
    {
        myValue = "test";
    }
    // Assuming setValue() has been run
    function getValue()
    {
        alert(window.myValue); // yup, it's "test"
    }

So if we use this knowledge to store $.ajax data in a variable it will go like this.

    var xml;

    $.ajax({
        type: "GET",
        url: "/?do=getcontentadm1n&category=homepage",
        dataType: "json",
        success : function(data) {
            window.xml = data;
        }
    });

    alert(window.xml);

I think this will clear up quite alot for many people and get you to your answer. Thanks for reading my reply and the source: http://snook.ca/archives/javascript/global_variable

EDIT: As mentioned in the comment below, this only works when async = false.

Cariah
  • 41
  • 4
0

Just use a 'async:false' Ajax and don't user var keyword for making Global response.

0

@ggreiner: Forget about using functions in variables. You are confusing other users.

I'm a little angry, but nothing personal, there are NO solutions on Internet available to store AJAX data in the vars and use them in events.

NO NEED TO USE ANY FUNCTIONS IN VARIABLES like var dataStore = (function(){. This will call additional servers requests everytime you need data.

Here is the code for calling ajax ONCE and use it's data for any other events, functions. That was the MAIN CONCERT of 99% users asking for this

$(document).ready(function() {
    var html; // DEFINE VARS
    var css;
    var js;

    $('.editbutton').live('click', function() {
        $.ajax({
            async   : false, // !!!MAKE SURE THIS ONE IS SET!!!
            type    : "GET",
            url : "/?do=getcontent",
            data    : { category: category },
            dataType: 'json',
            success : function(data) {
                if (data.status == 'ok') {
                                html = data.html; // !!!STORE!!!
                                css = data.css;  // !!!STORE!!!
                                js = data.js;  // !!!STORE!!!
                }
                if (data.status == 'error') {
                    alert('ERROR!');
                }
            }
        });
    });

    // CALL ANY STORED VARIABLE FROM ANYWHERE

    $('.otherbutton').live('click', function() {
        alert(html); alert(css); alert(js);
    });

});
Alex G
  • 3,048
  • 10
  • 39
  • 78
  • 2
    all those caps are making your answer a lot harder to take seriously. Also, you're wrong about "this will call additional server requests everytime you need data", read the code again and understand it. It only makes one request. With regards to this solution, it is wrong. What happens if the user clicks `.otherbutton` before clickin `editbutton`. In that case the data has not been loaded, and will be null. – driangle Sep 19 '12 at 17:42
  • 1
    Why didn't you make it 1 year to post comment? – Alex G Sep 19 '12 at 22:17