This article guides you on how to create an Ionic Custom Loader by generating an Angular CLI component for example on App Init using RxJs.
Ionic Loader is an overlay that can be used to indicate activity while blocking user interaction. The loading indicator appears on top of the app's content and can be dismissed by the app to resume user interaction with the app.
Now, let's get started by creating a reusable loading component in Angular CLI.
Generate Loader Component
The loader component can be reused every time it's called. Under app folder
, create a folder called components
, to contain all of the reusable components in the project.
Under folder components
, generate a component called loader
by using the following command:
$component ng g c loader --skip-import
--skip-import
the option will ignore the module autogenerating under the app component. The reason is we will use this loader component every time we need it. Now, we create the module for the loader component
following command:
$component ng g m loader
Now you can start styling and structuring your component under html
, css/scss/less
and ts
file. Or, you can use my example as below:
import { Component, Input, OnInit } from '@angular/core';
@Component({
selector: 'app-loader',
templateUrl: './loader.component.html',
styleUrls: ['./loader.component.scss'],
})
export class LoaderComponent implements OnInit {
@Input() isLoader = false;
@Input() message: string;
constructor() {}
ngOnInit(): void {}
The variable isLoader
will trigger the loader as Angular Input, while the message will be the option for a loader with a message.
So, the structure of HTML will be something likes this:
<section *ngIf="isLoader" class="splash">
<div class="spinner">
<div class="dot1"></div>
<div class="dot2"></div>
</div>
<h6 *ngIf="message">{{ message }}</h6>
</section>
Now, let stying these 2 dots with some animations in scss file.
.splash {
position: absolute;
z-index: 99999999;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
background: var(--ion-color-primary);
.spinner {
margin: 100px auto;
width: 40px;
height: 40px;
position: relative;
text-align: center;
-webkit-animation: sk-rotate 2s infinite linear;
animation: sk-rotate 2s infinite linear;
}
h6 {
margin: 0px;
color: var(--ion-color-secondary);
font-weight: 200;
font-size: 16px;
}
.dot1,
.dot2 {
width: 60%;
height: 60%;
display: inline-block;
position: absolute;
top: 0;
background-color: var(--ion-color-secondary);
border-radius: 100%;
-webkit-animation: sk-bounce 2s infinite ease-in-out;
animation: sk-bounce 2s infinite ease-in-out;
}
.dot2 {
top: auto;
bottom: 0;
-webkit-animation-delay: -1s;
animation-delay: -1s;
}
@-webkit-keyframes sk-rotate {
100% {
-webkit-transform: rotate(360deg);
}
}
@keyframes sk-rotate {
100% {
transform: rotate(360deg);
-webkit-transform: rotate(360deg);
}
}
@-webkit-keyframes sk-bounce {
0%,
100% {
-webkit-transform: scale(0);
}
50% {
-webkit-transform: scale(1);
}
}
@keyframes sk-bounce {
0%,
100% {
transform: scale(0);
-webkit-transform: scale(0);
}
50% {
transform: scale(1);
-webkit-transform: scale(1);
}
}
}
Finally, you need to declare this component inside its module:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { LoaderComponent } from './loader.component';
@NgModule({
declarations: [LoaderComponent],
imports: [CommonModule],
exports: [LoaderComponent],
})
export class LoaderModule {}
The loader following the code above will look like the Codepen project below. You can come up with another idea for loading.
See the Pen
2 Dots Loading Animation by Kent Wynn (@kentwynn)
on CodePen.0
Create Loader Service
We need the have a service to control the hide/show of our Ionic Custom Loader. Under app folder
, create a folder called services
.
The service folder will be the bridge the connections among components, like the middle man. The concept of service in Angular simply is to send & retrieve data throughout variables or functions.
Generate a service name loading.service.ts
. Here is the example of our loading service:
import { Injectable } from '@angular/core';
import { LoadingController } from '@ionic/angular';
@Injectable({
providedIn: 'root',
})
export class LoadingService {
private loader: HTMLIonLoadingElement;
constructor(public loadingController: LoadingController) {}
async showLoader(message = ''): Promise<void> {
this.loader = await this.loadingController.create({
cssClass: 'loader',
message: `
<div class="spinner">
<div class="dot1"></div>
<div class="dot2"></div>
</div>
<h6>${message}</h6>
`,
});
await this.loader.present();
}
async hideLoader(): Promise<void> {
await this.loader.dismiss();
}
}
2 Ways For Using The Ionic Custom Loader
Loader component can be used throughout the functions of any components using service or attach it in the HTML document by sending the Input
variables.
#1 By Service
In any components that you want to call the Ionic Custom Loader, simply declare it inside the construction of the component as follow:
constructor(
private loadingService: LoadingService,
)
For example, we want to show the loader during the time of getting information from Google Authorization when the user login. And, we will hide the loader when getting user information successfully or getting errors.
async googleAuth(): Promise<void> {
try {
await this.loadingService.showLoader();
const googleUser = (await Plugins.GoogleAuth.signIn()) as IGoogleAuthResponse;
await this.firebaseAuthGoogle(googleUser);
await this.loadingService.hideLoader();
await this.navigateToHome();
} catch (error) {
console.log('Login => error', error);
const message = this.translate.instant(
'Something went wrong Please Try again'
);
await this.successErrorAlert.showErrorAlert(message);
await this.loadingService.hideLoader();
}
}
#By Loader Component
Another case is that we want to show the Ionic Custom Loader by using a component in HTML and hide it when the Input value change.
In loader component, @Input() isLoader = false;
will define when our loader will be a trigger.
For example, I want to attach the loader when the app is loading/inits after a specific amount of time. First, we need to import the LoaderModule inside the module of the component that we want to use loader.
In our case, we will import LoaderModule
inside AppModule
as following:
@NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [
LoaderModule,
],
providers: [
],
bootstrap: [AppComponent],
})
export class AppModule {}
Now in the HTML of App Component, we can attach the loader component and trigger it by using the Angular Input.
<app-loader [isLoader]="showSplash"></app-loader>
<ion-app>
<ion-router-outlet></ion-router-outlet>
</ion-app>
Now, let say I want to trigger the loader show and then hide after 3 seconds, we may need the help of timer operation
in RxJs.
import { timer } from 'rxjs';
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.scss'],
})
export class AppComponent implements AfterViewInit {
showSplash = true;
constructor(
private platform: Platform,
) {
this.initializeApp();
}
initializeApp(): void {
void this.platform.ready().then(() => {
timer(3000).subscribe(() => (this.showSplash = false));
});
}
}
Conclusion
The article introduces one of the ways to generate an Ionic Custom Loader using Angular CLI. Moreover, you have learned about how to use Angular Input(), Angular Service, Reusable Component, and RxJs Operator.
Read more: Upper Lever Of Writing JavaScript In Frontend Architect
However, Angular or RxJs has many more features that we could discover in other articles. And, the concept of Loader can even apply in any Angular project rather than in the scope of Ionic.