2

I am trying to write code in javascript that will run a PHP script with an AJAX request, dynamically download its progress, display a progress bar and return current messages.

The solution works halfway because I can't solve two errors:

  1. Feedback messages are duplicated, it shows:

Set up... Set up... Analyzing... Set up... Analyzing... Exit

Instead

Set up... Analyzing... Exit

  1. I can't calculate the exact progress bar because e.total is 0 when using ob_flush () and flush ()

It is worth mentioning that the number of return messages each time the script is run will be different (dynamic), hence I cannot calculate the total value as in the examples available on the Internet.

$('#import').on('submit', function(e) {

  e.preventDefault();

  $.ajax({
    url: $(this).prop('action'),
    method: $(this).prop('method'),
    xhrFields: {
      onprogress: function(e) {
        $('#logs').append('<p>' + e.target.responseText + '</p>');
        $('progress').val((e.loaded / e.total) * 100);
      }
    },
    success: function(response) {
      console.log(response);
    }
  });

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="import" method="POST" action="import.php">
  <div id="logs"></div>
  <progress max="100" value="0"></progress>
  <button type="submit">Run</button>
</form>

This is the content of the import.php file for testing purposes:

echo 'Set up...';
ob_flush();
flush();
sleep(1);
    
echo 'Analyzing...';
ob_flush();
flush();
sleep(1);
    
echo 'Exit';
ob_flush();
flush();
sleep(1);
Montana
  • 93
  • 6

1 Answers1

3

You could save the previous response in a temporary var. And then compare if the previous response is the same as the current response.

$('#import').on('submit', function(e) {


  e.preventDefault();
  var previousResponse = ''

  $.ajax({
    url: $(this).prop('action'),
    method: $(this).prop('method'),
    xhrFields: {
      onprogress: function(e) {
        var response = e.target.responseText

        if(previousResponse !== response){
          $('#logs').append('<p>' + response + '</p>');
        }
        var previousResponse = response

        $('progress').val((e.loaded / e.total) * 100);
      }
    },
    success: function(response) {
      console.log(response);
    }
  });

});
anianweber
  • 31
  • 4
  • Thanks for this reply but your case will never exists. The php script returns each line executed sequentially, adding it to the previous ones. Hence test... !== test... test2... Instead of filtering the response on the client side, I would prefer to eliminate the error at backend – Montana Jun 01 '21 at 19:19
  • When i use substring from this reply: https://stackoverflow.com/a/42083534/8375683 it works correctly but still i don't know how can i get e.total – Montana Jun 02 '21 at 09:36