Debounce visibility of elements. This is especially useful with spinners. Read the Context for more information.
This is library helps you achieve this in Angular:
Wait X milliseconds before showing this element. If I cancel the operation before, do nothing.
npm i @omaxel/angular-show-debounce
This library exports a directive and a RxJS operator.
example.component.html
<div *omxDebouncedIf="loading">Loading...</div>
The div
element will be shown after 100ms since loading
is set to true
, unless loading
is set to false
before 100ms.
In order to use the directive, you must import it in your module:
import { DebouncedIfDirective } from "@omaxel/angular-show-debounce";
@NgModule({
imports: [BrowserModule, DebouncedIfDirective], // <-- Import the directive
declarations: [AppComponent],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
example.component.ts
import { showDebounce } from '@omaxel/angular-show-debounce';
...
loading$ = loadingSourceObservable.pipe(showDebounce());
The loading$
observable will emit true
after 100ms since loadingSourceObservable
emits the first true
, unless loadingSourceObservable
emits false
before 100ms.
You can specify your own value for the debounce time (default = 100) for both the directive and the RxJS operator:
Directive
<div *omxDebouncedIf="loading; debounce: 150">Loading...</div>
RxJS operator
loading$ = loadingSourceObservable.pipe(showDebounce(150));
For operations where it is unknown in advance how much work has to be done [...] use a less specific progress indicator in the form of a spinning ball, a busy bee flying over the screen, dots printed on a status line, or any such mechanism that at least indicates that the system is working, even if it does not indicate what it is doing.
We surely want to display a progress indicator while the application is executing a task, for example when calling APIs. Often times, we don't have progress to display. In that case we show an undetermined progress indicator, aka spinner.
Allegedly, we don't know the exact amount of time for the task to be completed. For this reason we usually end up with this kind of code:
showSpinner();
executeTask();
hideSpinner();
This code is safe since the user knows something is happening.
What happens, thought, when executeTask()
completes "almost" immediately? The user will assist to an appearing of the spinner immediately followed by its disappearing.
That's bad, don't you agree? The same article of the first quote continues:
0.1 second is about the limit for having the user feel that the system is reacting instantaneously, meaning that no special feedback is necessary except to display the result.
The application has 100ms to perform tasks. After that time, we must show something to the user.
The above code should now look like this:
showSpinnerIn100ms();
executeTask();
hideSpinnerIfItIsVisible();
This is conceptually easy. In Angular, the preferred way to show/hide elements is by using the *ngIf
directive. This directive accept a boolean parameter to decide whatever to the display the element or not.
However, there's no way to delay the element rendering. You could use an observable, but then you'll need to copy the same logic in all component's observable where you want to have that feature.
This library helps you in that goal by covering both cases: a custom *ngIf
directive and a RxJS operator.
Check the Usage section for more information.