amartin
amartin

Reputation: 350

Run jquery or javascript function while "waiting for server"

I have an asp.net MVC application, which is using minimal AJAX. I have some pages that require quite a bit of database work before the server responds with the HTML and data.

Depending on what the request was for and how many records a user has, there can be latency of several seconds or more after a user clicks a button or link (could be GET, POST, href, form submission, etc.), where the browser has submitted the request and is spinning its wheels waiting for a response, but has not yet loaded the new page, because the server has not returned anything yet.

Therefore, using document.ready and window.load etc. are not solutions that will work to trigger the loading spinner. I need something that starts as soon as a request to the server is made.

Furthermore, using something along the lines of

 $(document).click(function () {//start loading spinner here}

will also not work because there are elements all over the place that can be interacted with but do not make a server request (i.e. bootstrap nav panels, etc.)

I need to implement a loading spinner (or something similar indicating that work is being done and a response is coming) that runs when a request the server has been made, and the browser is "waiting for a response from server".

Update - Things I have tried:

This will trigger the loading spinner plug in loading.js when it's needed, but will also trigger it when it's not, such as when interacting with bootstrap UI elements, etc.

$(document).click(function () {
    //Start loading.js anytime a button is clicked
    //Show full page LoadingOverlay
    $.LoadingOverlay("show");
});

This doesn't work, because once the server returns a response (which is where the long latency is), there only fractions of a second left for the browser to render the HTML and display the view.

$(document).ready(function () {
// Show full page LoadingOverlay
$.LoadingOverlay("show");
});

$(window).on(load, function () {
    //Stop loading.js after page loads
    $.LoadingOverlay("hide");
});

Upvotes: 0

Views: 540

Answers (3)

Soviut
Soviut

Reputation: 91724

If these are full page refreshes, there's not much you can do. The page hasn't loaded yet because the server has literally returned nothing yet. So there's no html, javascript and no CSS present to display anything.

The way other slow/large sites typically deal with this is by loading the page without data, then making a separate data request via AJAX. This process is sometimes called "rehydrating" a page.

Using a data binding view model like VueJS would be a good idea since it makes populating the template with your returned data easy.

Upvotes: 1

iMatoria
iMatoria

Reputation: 1448

$("form").submit(function () {
  $('#loader').addClass("before").removeClass("after hide");
});
$(document).ready(function () {
  $("#loader").addClass("hide");
});
$(document).ajaxStart(function () {
  $("#loader").addClass("before").removeClass("after hide");
}).ajaxStop(function () {
  $("#loader").addClass("hide");
});
.before, .after{
  display:none;
  width: 50px;
  height: 20px;
  position:absolute;
  bottom: 10px;
  right: 10px;
}
.hide{
  display:none;
}
.show{
  display:block;
}

Hopefully this might help you.

Upvotes: 0

Soviut
Soviut

Reputation: 91724

You could simply assume that as soon as your page loads, you want to show a loading spinner. Then you would only hide it when one, or more, events complete.

  • Create an element that is always displayed on your page with a loading spinner image in it
  • Create a class specifically to hide the spinner (eg: .hide-spinner)
  • Wrap your jquery $.ajax() call inside a function (eg: fetch(url))
  • Inside the function, have jQuery remove the .hide-spinner class
  • In your .always() handler on the promise add the .hide-spinner class again
  • Return the ajax promise from the function so that you can continue to chain promise handlers from the returned result

You can now call that function from anywhere in your application and fetch the data you need and it will always show the spinner when it starts and hide it when it finishes.

Upvotes: 0

Related Questions