0

I'm new to ajax and its async nature, so I'm having several issues with that that this site helped me to solved, but I can't really get on this one.

Having a list: what I'm trying to do is to get the text of the element when clicking on it, and use it in the ajax call that fires.

The result of the ajax call should be stored in a global variable array (var results). The problem is that even though each ajax call does store the result in the specific position of the array, when I print the result, only the last value seems to be saved.

I have something like this:

<head>
    <script type="text/javascript">
        var webServiceURL;
        var soapMessage;

        var results = []; // array where each ajax call result will be stored

        var array= {"Mobile": 0,"TV": 1,"AirCon": 2,"Photo":3,"AudioSys": 4};  
           // depending on which element of the list I click, returns the position of the array where it has to store the result of the ajax call. 
           //For instance: when clicking on "Mobile", the ajax call should store the result in the index 0 of results, which we get by doing: array[Mobile]

        function ajaxCall(electronic_type){  
            webServiceURL = 'http://.....';  
            soapMessage = '<?xml version="1.0"....' + electronic_type + '.</S:Envelope>'; 

             var promise= $.ajax({
                    url: webServiceURL,
                    type: "POST",
                    dataType: "xml",
                    data: soapMessage,
                    processData: true,
                    contentType: "text/xml; charset=\"utf-8\"",
                    success: storeResult,
                    error: OnError
                });  
                promises.push(promise);
             function storeResult(text) {   
                      results[array[electronic_type]]=response_from_server;
             }
             $.when.apply(null, promises).done(function(){

                 // print results array to check if everything is stored.
                // do other stuff when all clicks have been processed
            });
        }
       $(document).ready(function () 
            if( request.getParameter("value") !== null){
                 String electronicType = request.getParameter("value");
                ajaxCall(electronicType);                   
            }                             
        });
    </script>    
</head>

</body>
    <ul>
        <li><a href="electronics.jsp?value=Mobile">Mobile Phones</a></li>
        <li><a href="electronics.jsp?value=TV">Television</a></li>
        <li><a href="electronics.jsp?value=AirCon">Air Conditioners</a></li>
        <li><a href="electronics.jsp?value=Photo">Photo & Optics</a></li>
        <li><a href="electronics.jsp?value=AudioSys">Audio Systems</a></li>
    </ul>
</body>

What happens is:

1st click on "Mobile": print of res[array[Mobile]] does have the result. 2nd clic on "TV": print of res[array[TV]] does have the result, but the previous one has disappeared.

Anyone knows what could be the issue? I've tried wrapping the ajaxCall() function in an anonymous function like said here but no luck.

Also: Ideally, the user should click in a link, wait for the ajax call to finish and show some info on the screen, and then is allowed to click in another link. Not sure if for this to happen I should set async: false, but either way it doesn't work since I have the same issue storing the results.

Many thanks.

Jack M.
  • 51
  • 7
  • Welcome to Stack Overflow. It looks like you're trying to define `results` in the `` and not within the ` – Twisty Jan 28 '19 at 00:19
  • @Twisty Thanks for the welcome. I made a mistake pasting the code here, all the variables are indeed declared inside ` – Jack M. Jan 28 '19 at 02:07
  • Is the result an array or arrays? `results[0][0]` or an array of objects: `results[0].mobile` ? – Twisty Jan 28 '19 at 02:14
  • `var array` indicates the index I will use to store each result in `var results`. For example: for "Mobile", I want to store it in `results[0]`, so I get the index by doing `array[Mobile]`. I check the result stored in the promises part and it works, however when I do several clicks `results` only has the last result I stored. – Jack M. Jan 28 '19 at 02:38

1 Answers1

0

Consider the following code.

<head>
<script type="text/javascript">
var results;
function ajaxCall(webServiceURL, soapMessage){  
  $.ajax({
    url: webServiceURL,
    type: "POST",
    dataType: "xml",
    data: JSON.stringify(soapMessage),
    processData: true,
    contentType: "text/xml; charset=\"utf-8\"",
    success: function(data){
      results.push(data);
    },
    error: function(chr, status, error){
      console.log("AJAX Error: " + status + ", " + error);
    }
  });
}
$(function (){
  if(request.getParameter("value") !== null){
    var electronicType = request.getParameter("value");
    ajaxCall("electronics.jsp", {value: electronicType});                   
  }                             
});
</script>    
</head>
</body>
<ul>
  <li><a href="electronics.jsp?value=Mobile">Mobile Phones</a></li>
  <li><a href="electronics.jsp?value=TV">Television</a></li>
  <li><a href="electronics.jsp?value=AirCon">Air Conditioners</a></li>
  <li><a href="electronics.jsp?value=Photo">Photo & Optics</a></li>
  <li><a href="electronics.jsp?value=AudioSys">Audio Systems</a></li>
</ul>
</body>

Now this is just sort of an example. Not sure what you intended to do with the promises, maybe there is something else related. Based on the way it's written are you planning ti fire the Ajax when the User clicks a link? If that is the case, you will want to do something like:

$(function (){ 
  $("li a").click(function(e){
    e.preventDefault();
    var parts = $(this).attr("href").split("?");
    var url = parts[0];
    var query = parts[1].split("=");
    ajaxCall(url, {query[0]: query[1]});                   
  }                             
});

This uses the <a> attributes and uses them in ajaxCall().

Hope this helps.

Twisty
  • 30,304
  • 2
  • 26
  • 45
  • Yes, I'm planning to fire the Ajax when the User clicks a link. I added the values of `webServiceURL` and `soapMessage` for clarification. The text of the link (for example, "Mobile") it's the only part that I need since it's part of the `soapMessage` and that's why I send it in `ajaxCall("Mobile")`. So I would have to call the function like this `ajaxCall(query[1]);` instead, right? The promises part is because I need to wait until I get the results of all the clicks made by the user so I can work with all of them. – Jack M. Jan 28 '19 at 02:52
  • @JackM.yes, if you want to send just `"mobile"`, this would be `query[1]`. – Twisty Jan 28 '19 at 08:05
  • If this has helped or answered your post, please upvote and mark it as the answer. – Twisty Jan 28 '19 at 08:10
  • tried it and works like a charm, thank you very much! – Jack M. Jan 28 '19 at 12:43