-1

ok so i am creating a web app and i have run into some issues

first i make a request to an api endpoint this returns a json response i take what i need and ad it into a key value array

i then have to loop through all the items in this array and for each item i need to make a request to a second api endpoint that returns some html

i need to then append this html to an eliment on the page

i need this to be done one after another the issue i have is that the .each() loop finishes instantly while the requests are still on going in the background meaning the aliments are appended to the html eliment on the page way after they should

how can i make the loop wait untill the requests are done and html is appended before moving onto the next item in the array

                    $("#middlebox").fadeTo(3000, 0, function() {
                
                    $("#middlebox").html(LOADING);
                    
                });
                
                $("#middlebox").fadeTo(3000, 1, function() {
                    
                    var API_URL = window.location.href + 'api.php?action=channels&category='+$this.data("text")+'&username='+$("#username").val()+'&password='+$("#password").val();
                    var CHANNELS = {};
                    var API_CHANNELS = '<div class="Live">';

                    $.getJSON(API_URL).done( function( API_RESULT ) {
                        
                        $.each( API_RESULT.items, function( API_INDEX, API_ITEM ) {
                            
                            var API_ID = API_ITEM.stream_id;
                            var API_ICON = API_ITEM.stream_icon;
                            
                            CHANNELS[API_ID] = API_ICON;
                            
                        });
                        
                    }).then( function() {
                        
                        $.each( CHANNELS, function( CHANNEL_KEY, CHANNEL_VALUE ) {
                            
                            var EPG_URL = window.location.href + 'api.php?action=epg&id='+CHANNEL_KEY+'&username='+$("#username").val()+'&password='+$("#password").val();
                            
                            API_CHANNELS += '<div class="channel focusable"><div class="LiveIcon"><img src="' + CHANNEL_VALUE + '" class="TvIcon"></div>';
                            
                            $.ajax({
                                url:EPG_URL,
                                type: 'GET',
                                dataType: 'html',
                                success:function(content,code) {
                                    API_CHANNELS += content;
                                }
                            });        
                            
                            API_CHANNELS += '</div>';

                        });
                    
                        $("#middlebox").fadeTo(3000, 0, function() {
                            
                            API_CHANNELS += '</div>';
                            
                            $("#middlebox").html(API_CHANNELS);
                            
                            $("#middlebox").fadeTo(3000, 1, function() {
                                
                            });
                            
                        });
                    
                    });
                    
                });
user72261
  • 11
  • 1
  • 5
  • To help you with that we need to see your code first :) – Kokodoko Mar 06 '22 at 17:50
  • edited with the current code i am using this code works and grabs the data needed and grabs the epg data needed but it is appended after everything else instead of inside its own
    – user72261 Mar 06 '22 at 17:54
  • AFAICT you are want your AJAX calls in order, is that correct? I searched for "*jquery ajax sequence*" and found many, many answers here already. Did you try those? https://stackoverflow.com/questions/1151598/how-to-make-all-ajax-calls-sequential, https://stackoverflow.com/questions/16384841/chain-ajax-and-execute-it-in-sequence-jquery-deferred, https://stackoverflow.com/questions/10980997/make-jquery-ajax-calls-in-order, https://stackoverflow.com/questions/5494057/jquery-ajax-sequential-calls, https://stackoverflow.com/questions/3034874/sequencing-ajax-requests, ... – Don't Panic Mar 06 '22 at 22:44

1 Answers1

0

Ajax calls are asynchronous so you can't use a synchronous loop to process the requests.

You can use Promise.all to wait for all ajax requests and then process replies in a loop.


Promise.all(CHANNELS.map(function( CHANNEL_KEY, CHANNEL_VALUE ) {
   var EPG_URL = window.location.href + 'api.php?action=epg&id='+CHANNEL_KEY+'&username='+$("#username").val()+'&password='+$("#password").val();
   return $.ajax({
        URL: EPG_URL,
        type: 'GET',
        dataType: 'html'
    }).then(function(content) {
       return [CHANNEL_KEY, CHANNEL_VALUE, content];
    });
})).then(function(channels) {
     $.each(channels, function(CHANNEL_KEY, CHANNEL_VALUE, content) {
         API_CHANNELS += '<div class="channel focusable"><div class="LiveIcon"><img src="' + CHANNEL_VALUE + '" class="TvIcon"></div>';
         API_CHANNELS += content;
         API_CHANNELS += '</div>';
     });
     $("#middlebox").fadeTo(3000, 0, function() {
       /* ... */
     });
});
jcubic
  • 61,973
  • 54
  • 229
  • 402
  • this is working perfect thank you just what i needed with some minor edits for other plugins i am using – user72261 Mar 07 '22 at 16:15
  • it should be noted that this does toss up one error jQuery.Deferred exception: CHANNELS.map is not a function TypeError: CHANNELS.map is not a function – user72261 Mar 07 '22 at 17:50
  • @user72261 not sure what browser you're using and what CHANNELS is but you can use `$.map(CHANNELS` but you need to check the order of arguments in a callback function, I've never remembered how jQuery have those, in Vanilla JavaScript it's more intitive. – jcubic Mar 08 '22 at 08:46
  • i am using the latest version of chrome and CHANNELS is a bassic key value array – user72261 Mar 08 '22 at 15:03
  • @user72261 there is no such thing as a key-value array. If you have `{x: y}` it's an object and you need a utility to integrate over (like jQuery `$.map`). Only real arrays [] have array methods. – jcubic Mar 08 '22 at 16:22