2

I am trying to implement an application wide, loading bar. So that when a user clicks any of the link in my application and while the data is being downloaded it should display a loading bar on top.

Something like this:

http://chieffancypants.github.io/angular-loading-bar/

Currently, what I have done is added a global singleton service with a Boolean property, isLoading. In my main app component template I have added angular material2 progress bar.

<md-progress-bar mode="indeterminate" *ngIf="_globalService.isLoading"></md-progress-bar>

Now, whenever I initiate an http request, I set isLoading property of that service to true in that component. And when that request completes I set it to false.

In my current case, I have to inject the service in my all of the components and manually set isLoading to true or false.

I was wondering is there any way to capture the initiation and completion of all ajax requests across my application, so that I just subscribe to that and don't have to handle it manually.

1 Answer 1

2

I can see two ways to do what you are after. The first one is to abstract all the Http requests to dedicated services, and the second is to wrap Http service.

Services. It is probably not the best idea to make Http requests from your component anyway, hence better approach would be to move http-stuff into dedicated services and set _globalService.isLoading flag from there. Component should not know about these things, it would only care about things like "getAccounts", etc. So abstracting actual Http request could make loading indicator flag hidden from component code.

Wrapping default Http service. It is totally possible to wrap Http service into one more layer from which isLoading flag could be set. In this case Component code would not know anything about loading indicator machinery too.

Possible wrapper could look something like this:

import {Http} from '@angular/http';
import {Injectable} from '@angular/core';
import {GlobalService} from './globalService';

export class HttpLoading extends Http {

  constructor(backend: ConnectionBackend, defaultOptions: RequestOptions, private _globalService: GlobalService ) {
    super(backend, defaultOptions);
  }

  get(url: string, options?: RequestOptionsArgs) {
    this._globalService.isLoading = true;
    return super.get(url, options)
      .map(res => {
        this._globalService.isLoading = false;
        return res;
      });
  }
}

and registered as

bootstrap(App, [
  GlobalService,
  HTTP_PROVIDERS,
  provide(Http, {
    useFactory: (backend: XHRBackend, defaultOptions: RequestOptions, globalService: GlobalService) => new HttpLoading(backend, defaultOptions, globalService),
    deps: [XHRBackend, RequestOptions, GlobalService]
  })
])

Demo: http://plnkr.co/edit/S5nSpscC3tIwX63lrBtO?p=preview

Sign up to request clarification or add additional context in comments.

5 Comments

Thank you so much dfsq for your reply, however I am receiving below errors when I try the 2nd approach. Error TS2322 Type 'Observable<Response>' is not assignable to type 'Promise<Response>'. Property 'then' is missing in type 'Observable<Response>'.
Error TS2415 Class 'HttpLoading' incorrectly extends base class 'Http'. Types of property 'get' are incompatible. Type '(url: string, options?: RequestOptionsArgs) => Promise<Response>' is not assignable to type '(url: string, options?: RequestOptionsArgs) => Observable<Response>'. Type 'Promise<Response>' is not assignable to type 'Observable<Response>'. Property '_isScalar' is missing in type 'Promise<Response>'.
It should be get(url: string, options?: RequestOptionsArgs): Observable<Response> { ... } and add import {Observable} from 'rxjs'.
Many thanks, that's awesome Aliaksandr, it really worked :)
Aliaksandr can you please suggest how to upgrade above code to RC 5? I have a open question with my attempt to migrate code to RC 5 but that doesnt seem to work stackoverflow.com/questions/38885912/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.