{JS} {Svelte} Display a Loader for a minimum amount of time.

ยท

2 min read

Sometimes, when we display a loader while data is being fetched/processed, the loading time is so short the loader flashes briefly. Here's how to fix it.

Please note: although the following examples are for Svelte, the logic can be adapted for other frameworks.

We start creating a class, I called it UseLoading but you can name it however you like.


import { writable } from "svelte/store";

export default class UseLoading {
    constructor(minTime = 0, isLoading = false) {
        this.minTime = minTime;
        this.startedTime = new Date();
        this.stoppedTime = new Date();
        this.isLoading = writable(isLoading);
    }

    start() {
        this.startedTime = new Date();
        this.isLoading.set(true);
    }

    stop() {
        this.stoppedTime = new Date();
        const difference =
            this.stoppedTime.getTime() - this.startedTime.getTime();

        if (difference > this.minTime) {
            this.isLoading.set(false);
        } else {
            setTimeout(() => {
                this.isLoading.set(false);
            }, this.minTime - difference);
        }
    }
}

Everything is self explanatory but I would like you to look at the minTime variable and stop method.

The minTime should hold the minimum time in milliseconds. The stop method will make sure that the minTime has passed before stopping the loader.

To use the class, we can do the following:

<script>
import Loading from "@/Shared/Loading";
import UseLoading from "@/Helpers/useLoading";

// we set to show the loader for at least 2sec
let loading = new UseLoading(2000);
let { isLoading } = loading;

const fetchData = () => {
    loading.start();

    axios.get("/your-data-endpoint").then((response) => {
        // handle response

        loading.stop();
    });
};
</script>

<div>
    <Loading active="{$isLoading}" />

    {#if !$isLoading}
        Show your data here
    {/if}
</div>

That's all to it.

If you have any questions, please leave a comment below.