0

I have a script that's 99% finished .. But I can't seem to get the very last portion of it figured out. My async: false is functioning correctly, as the ajax calls are made in succession in the function billAllDeadbeats. The issue I am having is simply with the widening of a div upon each succession. The script does make each ajax call in synch so would it stand to reason, that in the success method, that would also be synchronous? My progress bar is waiting until the billAllDeadbeats has finished instead of incrementally widening.

 $(document).on('click', '#billAllDeadbeatsButton', function () {
              hideElements().then(billAllDeadbeats);
});



        var hideElements = function() {
            var defer = $.Deferred();

            alert('hideElements() called');
            $('#collectAllHeader').hide();
            $('#collect_all_invoices_progress_wrapper').hide();
            defer.resolve();

            return defer;
        };
        
        
        
        var billAllDeadbeats = function() {
            var defer = $.Deferred();

            alert('billAllDeadbeats() called');
            setTimeout(function () {
                var current_count = 0;
                var percent = 0;
                var total_count = 0;
                $('.collectDeadbeat').each(function () {
                    total_count++;
                });

                // #################################  START EACH
                var def = [];
                $('.collectDeadbeat').each(function (i, obj) {
                    current_count++;
                    percent = current_count / total_count * 100;
                    def.push(prepareLayer($(this).attr('data-deadbeat-id'),$(this).attr('data-deadbeat-balance'),percent));
                });
                defer.resolve();
            }, 500);

            return defer;
        };
        
        function prepareLayer(id,balance,percent) {
            $.ajax({
                async: false,
                type: "POST",
                url: "collectAll.php",
                dataType: 'html',
                data: {id:id, balance:balance},
                success: function(id,balance){
                    $('#pay_all_loader_inner').css("width", Math.round(percent) + "%");
                    console.log(Math.round(percent));
                }
            })
        }
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#banner-message {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  font-size: 25px;
  text-align: center;
  transition: all 0.2s;
  margin: 0 auto;
  width: 300px;
}

button {
  background: #0084ff;
  border: none;
  border-radius: 5px;
  padding: 8px 14px;
  font-size: 15px;
  color: #fff;
}

#pay_all_loader_inner{
  height:30px; background-color:#FF0000; width:0%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="collectDeadBeat" data-deadbeat-id="1" data-deadbeat-balance="100"></div>
<div class="collectDeadBeat" data-deadbeat-id="2" data-deadbeat-balance="200"></div>
<div class="collectDeadBeat" data-deadbeat-id="3" data-deadbeat-balance="300"></div>
<div class="collectDeadBeat" data-deadbeat-id="4" data-deadbeat-balance="400"></div>
<div class="collectDeadBeat" data-deadbeat-id="5" data-deadbeat-balance="500"></div>
<div class="collectDeadBeat" data-deadbeat-id="6" data-deadbeat-balance="600"></div>
<div class="collectDeadBeat" data-deadbeat-id="7" data-deadbeat-balance="700"></div>
<div class="collectDeadBeat" data-deadbeat-id="8" data-deadbeat-balance="800"></div>
<div class="collectDeadBeat" data-deadbeat-id="9" data-deadbeat-balance="900"></div>


<div id="banner-message">
  <p>My Progress</p>
  <button id="billAllDeadbeatsButton">GO!</button>
  <div id="pay_all_loader_inner"></div>
</div>

I have read and read, and all the questions on SO point to the same thing .. Set the ajax call to asynch = false, and use then with defer to run my separate functions synchronously. Where am I going wrong?

I have used the following as references:

Make synchronous function in javascript?

each wait until finish $.ajax , and then continue

And they've gotten me super close, but no cigar. How can I make my progress bar incrementally follow the returns on the ajax calls?

Zak
  • 6,976
  • 2
  • 26
  • 48
  • with synchronous code, there's no time for rendering – Jaromanda X Aug 02 '18 at 22:51
  • @Jaromanda X -- OK -- If that's the case .. How do I go about what I am trying to accomplish? – Zak Aug 02 '18 at 22:52
  • chain the promises (or defered's as jQuery likes to call them) - `$.ajax` does return a promise – Jaromanda X Aug 02 '18 at 22:53
  • the defered returned in `hideElements` is pointless by the way - as is the one in `billAllDeadbeats` – Jaromanda X Aug 02 '18 at 22:55
  • Something like - https://jsfiddle.net/mh5rL87q/ - sorry, more like https://jsfiddle.net/mh5rL87q/2/ (missed a return) – Jaromanda X Aug 02 '18 at 23:06
  • The script in the JSFiddle calls all the ajax calls simultaneously -- instead of waiting until one finished to run the next one. – Zak Aug 02 '18 at 23:11
  • check the **second** fiddle - I forgot a return – Jaromanda X Aug 02 '18 at 23:12
  • actually - https://jsfiddle.net/mh5rL87q/5/ is probably even more correct – Jaromanda X Aug 02 '18 at 23:23
  • That last one is super close, although it's making 2 ajax calls together at a time. The reason I need it one at a time is our billing API only allows one connection at a time. – Zak Aug 02 '18 at 23:30
  • not sure why it would do 2 at a time rather than say all of them at once like when I forgot the return – Jaromanda X Aug 02 '18 at 23:40
  • [here's a fiddle](https://jsfiddle.net/pyc7hLvj/) that uses **real** Pormises rather than the buggy rubbish jquery passes off as promises (in early versions at least) – Jaromanda X Aug 02 '18 at 23:47
  • by the way, there was a problem with https://jsfiddle.net/mh5rL87q/5/ but it wouldn't have caused what you claim `return prepareLayer($(this).attr('data-deadbeat-id'),$(this).attr('data-deadbeat-balance') ,percent);` needed to be `return prepareLayer($(obj).attr('data-deadbeat-id'),$(obj).attr('data-deadbeat-balance') ,percent);` – Jaromanda X Aug 03 '18 at 00:07
  • I've used that code with a "dummy" ajax - https://jsfiddle.net/apwszeqx/10/ and, well, it definitely executes one "AJAX" at a time – Jaromanda X Aug 03 '18 at 00:10
  • hhmmm -- I am getting doubles for every call ... --> https://i.stack.imgur.com/7hJ99.png – Zak Aug 03 '18 at 00:34
  • So the same request twice. That's some other issue. – Jaromanda X Aug 03 '18 at 00:44
  • put a console.log at the top of the `click` handler - see if it's called more than once – Jaromanda X Aug 03 '18 at 01:03
  • Strange --> https://i.stack.imgur.com/gAFeU.png clicked once .. 2 calls is intermittent ... I suppose this will be a separate question. – Zak Aug 03 '18 at 02:58

0 Answers0