0

I'm trying to store data that I am retrieving from my JSON Ajax function. When I console output the data from inside the ajax function it works fine but when I try to do the same with the data variable it is failing.

Am I not storing the resulting data correctly?

function f_find() {

   // create my data object from the results

   var result = $.ajax({
      url      : '../scripts/php/users/f_users.php',
      type     : 'GET',
      dataType : "json",
      data     : {'action':'find'},
      success  : function(data) {

                    // this bit works

                    console.log(data[0]["field01"]);
                    console.log(data[1]["field01"]);

                 },
      error    : function(log) {
                    console.log(log.message);
                 }
   });

   // this shows me that my result is an object

   console.log(result);

   // this bit fails

   console.log(result[0]["field01"]);
   console.log(result[1]["field01"]);

}

The php is as follows

<?php

if(isset($_GET['action'])) {

   switch($_GET['action']) {

      case 'find':
         f_find();
         break;

      default:
         echo json_encode();
         return;
         break;

   }

}

function f_find() {

   $la_info = array();

   $la_info[0]["field01"] = "index 0 field 1";
   $la_info[0]["field02"] = "index 0 field 2";

   $la_info[1]["field01"] = "index 1 field 1";
   $la_info[1]["field02"] = "index 1 field 1";

   echo json_encode($la_info);

}

?>
2
  • Show us your PHP. Commented Nov 8, 2016 at 15:35
  • The data variable contains the result of the $.ajax call (which is not the response that you have inside the success function. Moreover - the code that fails probably runs before the ajax-call returned... Commented Nov 8, 2016 at 15:38

3 Answers 3

1

The ajax call happens asynchronously. The "failing" is actually just running before the ajax responds. Look in your console and notice that your two failing console.logs write to to the console BEFORE the two "working" console.log statements.

Also... the "data" variable will only be accessible within the scope of that "success" callback unless you store its value in the global scope. window.data = data;

Sign up to request clarification or add additional context in comments.

Comments

0

You have trouble with your scope.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions

Try this :

function f_find() {
   var ajaxResult = null;
   // create my data object from the results

   $.ajax({
      url      : '../scripts/php/users/f_users.php',
      type     : 'GET',
      async: false, 
      dataType : "json",
      data     : {'action':'find'},
      success  : function(data) {

                    // this bit works
                    ajaxResult = data;
                    console.log(data[0]["field01"]);
                    console.log(data[1]["field01"]);
                 },
      error    : function(log) {
                    console.log(log.message);
                 }
   });

   console.log(ajaxResult[0]["field01"]);
   console.log(ajaxResult[1]["field01"]);

}

When you receive data form ajax success they are now available in the ajaxResult var. In this example i said to ajax to be synchronous to prevent console.log call before you receive your ajax callback.

You can also do this with this notation :

function f_find() {
   // create my data object from the results

   $.ajax({
      url      : '../scripts/php/users/f_users.php',
      type     : 'GET', 
      dataType : "json",
      data     : {'action':'find'},
      error    : function(log) {
                    console.log(log.message);
                 }
   }).done(function(data){
       console.log(data[0]["field01"]);
       console.log(data[1]["field01"]);
   });

}

But you still can't access data outside of the done scope.

2 Comments

That wont work either. The ajax success callback will run AFTER those two console.log statements run.
@KevinGrosgojat you should edit your answer to advise that changing the default async to synchronous is going to cause blocking at the UI.
0

As @Dekel says, this is a timing issue (apart from the weirdness over the two data variables). Kevin Grosgojat's answer will still have the timing issue.

The $.ajax function is asynchronous. What that means is that the ajax function fires off the data request to the server and while that is being processed at the server, processing proceeds on to hit your two external console outputs however at this point in time the server has not responded and so there is no data to display. Some time later the server responds to the ajax call and your internal console logs spit out the answer that you anticipated.

'IF' your original code were to work for you now it would be because you have a very fast server or very small server process to get the data, but it would surely suffer and be an intermittent bug in production.

You 'could' add the parameter to the ajax function to make it run synchronously (meaning wait for server response) but that is rarely what you would truly want as the final solution.

7 Comments

What is the solution though, how can I get the data from this function so that I can use it?
I've just edited with some synchronous ajax, or with a done callback
With async you have to think about callback() functions. A callback() function is like saying 'when the ajax returns some data call this function'. In simple terms you take everything you want to do AFTER the ajax response and put it in a function which you then call from within the success() function of the ajax call. Just before you call the callback, you can do error checking on the response etc. Google callback functions for more info, there is loads out there.
Just read what i said, you can tell to ajax to be SYNCHRONOUS vith the async: false flag. I'm a javascript software Developper for 5 years now, i know how callbacks works ;-)
@KevinGrosgojat I worry that because the OP appears to be new to async calling via ajax (as witnessed by the misunderstanding implicit in the question) that suggesting he simply make the async call synchronous is not really helping him. Granted you might get the points for answering the question but it seems like a superficial answer to a deeper need.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.