Home > database >  Only show loading spinner on long requests
Only show loading spinner on long requests

Time:09-26

I'm trying to get a loading spinner to only display on requests greater than 200 ms. I thought I had it working, but it seems the events are fired out of order somehow.

This is from my loading-spinner.js class:

class LoadingSpinner {
    constructor(milliseconds) {
        this.timeoutId = null;
        this.milliseconds = milliseconds;
    }

    waitForLongRequest() {
        this.timeoutId = setTimeout(() => {
            console.log('waiting for long request');
            console.log(this.timeoutId);
            document.body.classList.remove("loaded");
        }, this.milliseconds);
    }

    cancel() {
        console.log('canceling long request');
        console.log(this.timeoutId);
        clearTimeout(this.timeoutId);
        document.body.classList.add("loaded");
    }
}

export default LoadingSpinner;

This is from my app.js:

import LoadingSpinner from './custom/loading-spinner.js';

document.addEventListener("DOMContentLoaded", () => {
    var ls = new LoadingSpinner(200);

    Livewire.hook('message.sent', (message, component) => {
        console.log('message.sent fired');
        ls.waitForLongRequest();
    });

    Livewire.hook('message.processed', (message, component) => {
        console.log('message.processed fired');
        ls.cancel();
    });
});

Here's the output from my console. The last request causes the spinner to show indefinitely.

enter image description here

CodePudding user response:

In addition to @user3252327 comments, this is the fix:

waitForLongRequest() {
    if (this.timeoutId) {
        this.cancel()
    }
    this.timeoutId = setTimeout(() => {
        console.log('waiting for long request');
        console.log(this.timeoutId);
        document.body.classList.remove("loaded");
    }, this.milliseconds);
}

Update: And for good measures we should reset this.timeoutId after cancel:

cancel() {
    console.log('canceling long request');
    console.log(this.timeoutId);
    clearTimeout(this.timeoutId);
    this.timeoutId = null;
    document.body.classList.add("loaded");
}
  • Related