Jitendra Solanki
Jitendra Solanki

Reputation: 391

Call common function before and/or after HTTP request in angular 2

I need to setup common loader into entire angular2 project. So i just want to do is when my new http call generate either it's GET, POST, or PUT then before request sent loader is appear. Once http response(success or error) arrive from server side then loader should be disappear.

There is any in built module available using that i can do above functionality. Or give me any way so i can do it with angular functions. I am using rxjs for http request.

I not want to use jQuery or Javascript.

Upvotes: 2

Views: 2576

Answers (3)

Garth Mason
Garth Mason

Reputation: 8011

Extending HTTP works well - in our project we also wanted explicit control of the 'loader' aka spinner for some scenarios. So we have a SpinnerService in our Core module that is available to all components.

@Injectable()
export class SpinnerService {

  private spinnerStateSource = new Subject<SpinnerState>();
  spinnerState$ = this.spinnerStateSource.asObservable();

  private defaultMessage: string = 'Loading...';

  show(message?: string) {

    let msg = this.defaultMessage as string;
    if (message) {
      msg = message;
    }

    this.spinnerStateSource.next({ showing: true, message: msg });
  }

  hide() {
    this.spinnerStateSource.next({ showing: false, message: '' });
  }

  spin(obs: Observable<any>, message?: string): Observable<any> {
    this.show(message);
    return obs.finally(() => this.hide());
  }

}

class SpinnerState {
  showing: boolean;
  message: string;
}

A component in the main module subscribes to the service to show/hide the actual spinner UI (EDIT: just like in @Gunter's answer), and other components can (via the service) tell the spinner to show/hide.

An example where we use that is if a component has to make multiple HTTP calls to e.g. get some reference data, then we want the spinner to show til all those calls are done. So we call the spin function with the action we are waiting on

e.g. in the consuming component:

this.spinnerService.spin(
     Observable.forkJoin(
       this.refDataService.getRefDataList('statusTypes'),
       this.refDataService.getRefDataList('itemTypes')
     )
 ).subscribe(result => {
             this.statusTypes = result[0];
             this.itemTypes = result[1];
 });

Upvotes: 2

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 658017

@Injectable()
class MyService {
  private change:Subject<boolean> = new BehaviorSubject(false);
  public change$ = this.change.asObservable();

  constructor(private http:Http) {}

  get(...) {
    this.change.next(true)
    return this.http.get( ... )
    .map( ... )
    .finally(_ => this.change.next(false);
  }
}
@Component({
  selector: 'loader',
  template: `
  <div *ngIf="myService.change | async">is loading ...</div>
`
)}
class LoaderComponent {
  constructor(public myService:MyService){}
}

Upvotes: 1

Slava.K
Slava.K

Reputation: 3080

Create http interceptor and call your common functions inside it. You may either write your own interceptor implementation like this or use an external library

Upvotes: 2

Related Questions