Omri
Omri

Reputation: 1656

Issue with getting response in Ajax

I have the following code:

  function f(){
      var value = "";
      var request1 = $.ajax({
           url : '/a',
           type: "GET"
      });
      var request2 = $.ajax({
          url: '/b', 
          type: 'GET',
      });

      $.when(request1, request2).done(function(result1, result2){

      //break point #1
      //result1 = [Object, "success", Object]
      //result2 = [Object, "success", Object]

      //do something
      })

     //break point #2
     //request1 = Object {readyState: 1}
     //request2 = Object {readyState: 1}

     return value
  }

When i out the a break point on one place i get that result1 = [Object, "success", Object] and when i out it on the other place i get that request1 = Object {readyState: 1}. Please see above.

  1. What could be the reason for this issue? Is that async issue?
  2. I want to insert the return value into a parameter. For example: a = f(). Is that something i should do with a callback? I've tried to read some articles about it, but haven't managed to implement it, so i would like to get some help. I don't have a lot of experience with JavaScript, so i have some difficult yet to implement such as kind of things.

Upvotes: 1

Views: 60

Answers (1)

fikkatra
fikkatra

Reputation: 5822

Yes, that is because of async functionality. Any code that you want to execute after the call returns, whether it's checking the result or asigning the return value to a variable, should be placed inside the callback. At breakpoint #2, you're 'stepping over' the async call and you have no control over the state of this call. So place all code in the callback, i.e. at breakpoint 1.

To assign the result of your 'f' function to a variable, e.g. var r = f(), with f depending on async ajax calls, you need to turn the 'f' function into an asynchronous function, e.g. by using jQuery's Deferred object or by using ES6 built in promises. This way, you can assign the result of f when f resolves, which is when all ajax requests resolve.

In the following code snippet I simulated the ajax calls by replacing them with asynchronous functions, to turn it into a working snippet. I turned f into an asynchronous function as well, by letting it return a Deferred object.

$(document).ready(function() {
  function f() {
    var value = $.Deferred(); //this is the result this function will return
    
    //simulate ajax call 1
    var request1 = function() {
      var result = $.Deferred();
      result.resolve("this is the result of request 1");
      //result.reject("something went wrong in request 1");
      return result;
    };
    //simulate ajax call 2
    var request2 = function() {
      var result = $.Deferred();
      result.resolve("this is the result of request 2");
      //result.reject("something went wrong in request 2");
      return result;
    };

    $.when(request1(), request2()).done(function(result1, result2) {
      alert("result 1: " + result1);
      alert("result 2: " + result2);
      value.resolve(result1 + ' ' + result2); //assuming the result of the f function is a concatenation of both requests
    }).fail(function(err) {
      alert("error occurred while executing request 1 or 2: " + err);
      value.reject(err);
    });


    return value;
  }
  
  
  //call f function. Asign result asynchronously
  $.when(f()).done(function(result) {
    //f has 'resolved'
    alert("result of f: " + result);
  }).fail(function(err) {
    alert("error while executing f: " + err);
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Upvotes: 2

Related Questions