2

I am using ajax to get some values from a database. In my java script file I have a global variable that some functions need to access it. I need to fill that variable from the values from the database. When I use ajax then the variable stays empty. If I use the async:false in my ajax code I get that warning message in my browser's dev tools:

jquery-3.2.1.min.js:4 [Deprecation] Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.

Moreover using the above it doesn't fill the variable resulting to errors in the other functions. Plus, from what I read this is deprecated and should not be used in any circumstances.

my code

var array ={};
var flag = 'true';
        $.ajax({
            url: "name.php",
            method: "post",
            data:{flag:JSON.stringify(flag)},
            success: function(data) {
                array = JSON.parse(data);

            },
             async: false,
            error: function(xhr, ajaxOptions, thrownError) {
            console.log(thrownError);
            }
        });

What, basically I'm trying to do, is to fill the array variable and make it an proper array.

the data from the the database is like this

{ 'something': { 'act1': 'act1a','act2': 'act2a'}, 'something2': { 'act1': 'act1a','act2': 'act2a'} }

anyone have any suggestions on how to achieve that?

PS: I need to fill a variable with the ajax response which will be accessible by other functions... not Convert a JSON Object into Javascript array...Im retrieving the data in string format

johnmmm
  • 115
  • 4
  • 11
  • What do you want to fill the `array` variable with? Is `headers_array` just a typo? – Luca Kiebel Dec 06 '17 at 16:43
  • What does `data` look like in the success function when you debug it? – Matt Spinks Dec 06 '17 at 16:44
  • Another way to do this would be to pass the ajax promise around. If you passed the promise to the method that needs it, some time in the future, that method could attach a `then()` to the promise to get the value. If the promise has already resolved that `then` will immediately fire and perform whatever logic you want it to with the response passed in to that callback. – Taplar Dec 06 '17 at 16:45
  • @MacroMan sorry that was my mistake.. the actual variable is array – johnmmm Dec 06 '17 at 16:46
  • @MattSpinks if i log this array = JSON.parse(data) the array it outputs the desirable outcome but still is not accessible by the other functions – johnmmm Dec 06 '17 at 16:48
  • @Taplar can you give me an example please as I'm not familiar with promises? – johnmmm Dec 06 '17 at 16:48
  • What do you mean by 'not accessible'? Is it empty? or undefined? – Matt Spinks Dec 06 '17 at 16:50
  • 2
    never use async:false... – noel293 Dec 06 '17 at 16:50
  • 2
    @johnmmm that's definitely a concept you should become familiar with. I'd advise giving http://learn.jquery.com/ajax/ a read. I'll put together a short example in an answer what I'm suggesting too. – Taplar Dec 06 '17 at 16:50
  • Possible duplicate of [Converting JSON Object into Javascript array](https://stackoverflow.com/questions/20881213/converting-json-object-into-javascript-array) – SierraOscar Dec 06 '17 at 16:50
  • And why are you using `async:false`? You want this to be asynchronous. – Matt Spinks Dec 06 '17 at 16:51
  • @MattSpinks it is empty... e.g. one function will should go through the array and act accordingly on the values of it and make some changes on the screen. but it doesn't... if i hard code the array then it works but i need to access it from the database. does that make sense? – johnmmm Dec 06 '17 at 16:53
  • I'd recommend localStorage over global variables in JavaScript due to persistence. If you want to keep it just for that session then use sessionStorage. Just something to look into. – Tubs Dec 06 '17 at 17:04
  • @Tubs localStorage or sessionStorage can't be the case in here as the changes that will occur must be persistent even if the user is on different computer – johnmmm Dec 07 '17 at 09:39
  • @johnmmm wait, what? You do know JavaScript (and the variable values) only exist in that instance right? It's not like a `static` method in a compiler language... – Tubs Dec 07 '17 at 09:50
  • @Tubs wait, what? have you read the question? I'm retrieving the data from a database using ajax and i need to save them in a global variable so they can be accessible by other functions in the script – johnmmm Dec 07 '17 at 10:16
  • What are you talking about that it needs to be persistent even if the user is on a different computer? No JavaScript can handle that. "save them in a global variable" - That's precisely what you can do with localStorage and sessionStorage. Also persists the value when the JavaScript is either refreshed or navigation occurs. – Tubs Dec 07 '17 at 11:52

3 Answers3

3

Based on your question and code, I think you are trying to access your array object before it is loaded with data. First of all, you will need to remove async:false. You want this to be asynchronous. That's the nature of ajax. Secondly, make sure you "do stuff" with array after the ajax call completes. For example, this will not work:

var array ={};
var flag = 'true';
$.ajax({
    url: "name.php",
    method: "post",
    data:{flag:JSON.stringify(flag)},
    success: function(data) {
        array = JSON.parse(data);
    },
    error: function(xhr, ajaxOptions, thrownError) {
        console.log(thrownError);
    }
});
//DO STUFF WITH array here.. will not work

But this will work:

var array ={};
var flag = 'true';
$.ajax({
    url: "name.php",
    method: "post",
    data:{flag:JSON.stringify(flag)},
    success: function(data) {
        array = JSON.parse(data);
        //DO STUFF WITH array here..
    },
    error: function(xhr, ajaxOptions, thrownError) {
        console.log(thrownError);
    }
});

One more thing to consider here - It's common practice to create a function outside your ajax success function to do something with your data (array), and call that function from inside your success function:

var array ={};
var flag = 'true';
$.ajax({
    url: "name.php",
    method: "post",
    data:{flag:JSON.stringify(flag)},
    success: function(data) {
        array = JSON.parse(data);
        doStuffWithArray(array);
    },
    error: function(xhr, ajaxOptions, thrownError) {
        console.log(thrownError);
    }
});

function doStuffWithArray(myArray) {
    //DO STUFF HERE...
}
Matt Spinks
  • 6,380
  • 3
  • 28
  • 47
  • I know that if I use everything inside the success will work but I cannot do it in that case – johnmmm Dec 07 '17 at 09:37
  • I think you are going to need to figure out a way to "do your stuff" after the `success` function fires. That's just the nature of ajax. You have to wait to get your data before you can do anything with it. Why do you say you "cannot do it in that case"? Also, you can create a function **outside** the success handler, and then just call that function from inside the success handler. Check my updated answer for an example of that. – Matt Spinks Dec 07 '17 at 14:45
1

So lets say you have an ajax call that you are making to and endpoint, whose response you may want to use at a later time, not immediately upon the success of the ajax call, for whatever reason. One way to do that is to pass around the promise/deferred that the $.ajax method returns. With this object you can attach any of the promise/deferred methods for handling the resolution or rejection of the promise. For instance:

//first we'll create a dummy deferred.  we will pretend that this is our ajax call.  in actual code this would look something like
//var dummyDeferred = $.ajax(...);
var dummyDeferred = $.Deferred();

//lets say, maybe you do want something to happen immediately upon the request success.  you can do that.
dummyDeferred.then(function(data){
  console.log("immediate then", data);
});

//now lets say that the ajax finishes, you should see the console log as you'd expect from the above then()
dummyDeferred.resolve("hello!");

//now lets say that some time later, you want to use that result inside another method to do something.  to do that you can simply attach another then() to the promise/deferred
//we'll use a timeout to simulate later usage of the promise/deferred
setTimeout(function(){
  doOtherStuff(dummyDeferred);
}, 5000);

function doOtherStuff(promise) {
  //maybe you want to take the data response and put it on the page some how.  you can!
  promise.then(function(data){
    $(document.body).append(data);
  });
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Taplar
  • 24,788
  • 4
  • 22
  • 35
1
var array;
var flag = 'true';
        $.ajax({
            url: "name.php",
            method: "post",
            data:{flag:JSON.stringify(flag)},
            success: function(data) {
                array = JSON.parse(data);
                function_ThatNeeds_Thearray();

            },
             async: false,
            error: function(xhr, ajaxOptions, thrownError) {
            console.log(thrownError);
            }
        });
johnmmm
  • 115
  • 4
  • 11