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);

1 Answer 1

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);
    }
  });

});
Sign up to request clarification or add additional context in comments.

2 Comments

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
When i use substring from this reply: stackoverflow.com/a/42083534/8375683 it works correctly but still i don't know how can i get e.total

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.