Reputation:
Here is my code below StaffMembers.ts component.
import { Component, OnInit } from '@angular/core';
import { StaffService } from '../_services/Staff.service';
import { Router, NavigationExtras } from "@angular/router";
@Component({
selector: 'StaffMembers',
templateUrl: './StaffMembers.html'
})
export class StaffMembers implements OnInit {
public StaffArr: Array<any>;
constructor(private _StaffService: StaffService, private _router: Router) {
}
async ngOnInit() {
this.StaffArr = await this._StaffService.GetStaff();
}
}
Here is my Staff.service.ts service component below.
import { Injectable, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { BehaviorSubject, Observable, Subject } from 'rxjs';
import { HostedPathConst } from '../_helpers/path';
@Injectable({
providedIn: 'root'
})
export class StaffService {
private messageStaffSource: BehaviorSubject<Staff>;
public currentStaffMessage: Observable<Staff>;
private _Staff: Staff;
private ProfileFile: FileList;
private sL: Array<Staff> = new Array();
constructor(private http: HttpClient, private toastr: ToastrService) {
this.messageStaffSource = new BehaviorSubject<Staff>(new Staff());
this.currentStaffMessage = this.messageStaffSource.asObservable();
}
GetStaff(): Promise<any> {
const promise = this.http.get(HostedPathConst.HostedPath + `Staff/GetStaff`).toPromise();
return promise;
}
Error(data) {
}
Success(data) {
this.toastr.success(data.errorMessage, 'Success !');
}
}
Now as i want to add my loader on the page i have found a package from this URL which is working as expected.
https://www.npmjs.com/package/@tusharghoshbd/ngx-loader
As i use it in any HTML page its called by this way.
<ngx-loader [show]="show" [fullScreen] = "fullScreen" [template]="template"> Loading... </ngx-loader>
and in any component file its called like this way.
//Declaration
show = false;
fullScreen = true;
template = ``
//Initialization
this.show = true;
this.fullScreen = true;
this.template = ``;
//And to stop the loader
this.show = false
Now as i have above two unrelated components
StaffMembers.ts for html component and for service Staff.service.ts now as i want to use the spinner or loader when the data is being fetched from the
async ngOnInit() {
this.StaffArr = await this._StaffService.GetStaff();
}
How can i wait for my data being loaded to start and stop the loader or spinner.
Upvotes: 1
Views: 842
Reputation: 26372
If you want to keep them separated (and you should) I would use an http interceptor.
There is an excellent example on medium: https://medium.com/swlh/angular-loading-spinner-using-http-interceptor-63c1bb76517b
Check the code:
import { Injectable } from '@angular/core';
import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor, HttpResponse
} from '@angular/common/http';
import { Observable } from 'rxjs';
import {catchError, map} from 'rxjs/operators'
import {LoadingService} from '../../layout/services/loading/loading.service';
/**
* This class is for intercepting http requests. When a request starts, we set the loadingSub property
* in the LoadingService to true. Once the request completes and we have a response, set the loadingSub
* property to false. If an error occurs while servicing the request, set the loadingSub property to false.
* @class {HttpRequestInterceptor}
*/
@Injectable()
export class HttpRequestInterceptor implements HttpInterceptor {
constructor(
private _loading: LoadingService
) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this._loading.setLoading(true, request.url);
return next.handle(request)
.pipe(catchError((err) => {
this._loading.setLoading(false, request.url);
return err;
}))
.pipe(map<HttpEvent<any>, any>((evt: HttpEvent<any>) => {
if (evt instanceof HttpResponse) {
this._loading.setLoading(false, request.url);
}
return evt;
}));
}
}
In this example, the author uses a service to share change in state. You could use events too, but it would be trickier as it's out of the running scope of angular
Upvotes: 1