Arnaud Spaeth
Arnaud Spaeth

Reputation: 11

Display a spinner while sending a sync Ajax request

I need to display a spinner while sending a synchronous Ajax request to the server to retrieve data.

I know it is better to do it in asynchronous mode but I'm not allow to do it. I also know sync ajax request blocks the browser.

I already found a solution with a setTimeout to delay the call of my ajax request but my boss doesn't want me to use setTimeout.

Do you have any solution to solve my problem please ? Thank you very much !

Upvotes: 0

Views: 3978

Answers (7)

Mark Schultheiss
Mark Schultheiss

Reputation: 34227

Quite late here but here is another method using the updated ajax methods; ugly but just to demonstrate the use.

function doAjaxCall() {
  const spinner = $('.spinner-fun');
  const url =  "Idonotexist";
  $.ajax({
    data: "",
    url: url,
    beforeSend: function(xhr) {
      spinner.toggleClass("hidden");
    }
  }).done(function(result) {
    //Show success message
    $(".success-message").toggleClass("hidden", 3000);
  }).fail(function(data) {
    //Show error message
    $(".fail-message").append(` URL:${url}`).toggleClass("hidden", 3000);
  }).always(function() {
    spinner.toggleClass("hidden", 3000);
  });
}
setTimeout(doAjaxCall, 4000);
.hidden {
  display: none;
}

.spinner-fun:not(.hidden) {
  display: grid;
  place-items: center;
  background-color: #00ff0020;
  padding: 1em;
}

.success-message:not(.hidden),
.fail-message:not(.hidden) {
  display: grid;
  place-items: center;
  padding: 1em;
}

.fail-message {
  color: #FF0000;
  border: solid 2px #FF0000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<div class="fun-guys">In 4 seconds we fire the ajax call; then in 3 seonds after that completes we fade out the spinner</div>
<div class="spinner-fun messages hidden">Hi I am spinner; in 3 seconds after the ajax call I fade out</div>
<div class="success-message messages hidden">WOO HOO we did it</div>
<div class="fail-message messages hidden">Something went wrong</div>

Upvotes: 0

Kerry
Kerry

Reputation: 161

Adding to the solutions above (which I already had, but didn't work):

I had async:false, in my ajax call that I had copied from some example, which of course breaks the simultaneous front-end spinner update. A no-brainer when you think about it, but it was nowhere explicitly shown in the above examples.

So, async:true finally fixed it.

Upvotes: 0

Dumisani
Dumisani

Reputation: 3048

Jquery has some ajax event handlers. You can use

$( document ).ajaxStart(function() {
  $( "#loading" ).show();
});

to show the loading image when sending the request and

$( document ).ajaxComplete(function() {
  $( "#loading" ).hide();
});

to hide the loading image when the request is complete.

REF: https://api.jquery.com/ajaxStart/ and http://api.jquery.com/ajaxcomplete/

Upvotes: 2

Rajan Benipuri
Rajan Benipuri

Reputation: 1832

You can make use of AJAX beforeSend success error or complete function. Or you can simply show a spinner before AJAX call and hide it in your success or error or complete function depending on your requirement.

Sample Code :

  $('.spinner-div').show();
  $.ajax({
  //You AJAX function
  success: function(){
     $('.spinner-div').hide();
     //Show success message
  },
  error : function(){
     $('.spinner-div').hide();
     //Show error message
  }
  });

Upvotes: 2

RussAwesome
RussAwesome

Reputation: 464

You can do this by rendering a 'static' gif to the page, and making your script replace the content of the div with the results of the AJAX call. This will effectively show a 'loading' icon until the results load, but if there is an error from your script then the gif will spin forever.

            <div id="chart_score" style="width: 100%; height: 300px;">
                <div style="text-align: center; height: 100%;">
                    <br />
                    <br />
                    <br />
                    <img src="../../Img/GIF/CircleLoader.gif" />
                    <br />
                    <br />
                    Loading chart...
                </div>
            </div>

Upvotes: 0

Zenoo
Zenoo

Reputation: 12880

You could simply show your spinner before your AJAX call, then hide it inside the success & error of your AJAX call :

$('#spinner').show(); //Show your spinner before the AJAX call
$.ajax({
  url: "test.html",
  method: 'POST',
  success: function(data){
    $('#spinner').hide(); //Hide your spinner after your call
  },
  error: function(){
    setTimeout(() => { //I'm setting a setTimeout here so you have the time to see the spinner.
                       // Remove it when you copy this code.

      $('#spinner').hide(); //Hide your spinner after your call
    },2000);
  }
});
#spinner{
  display: none;
  width: 10px;
  height: 10px;
  animation: rotating 2s linear infinite;
}

@keyframes rotating {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="spinner">0</div>

Upvotes: 1

ikdekker
ikdekker

Reputation: 425

there is a .success() method on ajax requests.

heres some examples of how it can be used jQuery: Return data after ajax call success

There is some debate about deprication here though Should I use .done() and .fail() for new jQuery AJAX code instead of success and error

Upvotes: 1

Related Questions