I created a loading spinner component for my <strong>angular 4</strong> app that should show during AJAX calls but I have trouble displaying it with a subscription to a <strong>BehaviorSubject</strong>.
This question is related to <a href="https://stackoverflow.com/questions...ime-data-recieved-from-the-server-in-angular2">how to show a spinner till the time data recieved from the server in angular2</a> but not a duplicate (as I want to do it with a reusable component) and <a href="https://stackoverflow.com/questions...js-behaviorsubject-subscribe-call-not-working">Angular 2 + RxJS BehaviorSubject subscribe call not working</a> (Though I don't see any difference between my code and the accepted answer. Did I miss something?)
I basically followed this tutorial <a href="https://hassantariqblog.wordpress.c...-spinner-as-service-in-angular-2-application/" rel="nofollow noreferrer">https://hassantariqblog.wordpress.c...-spinner-as-service-in-angular-2-application/</a>
Here's some of my code:
<strong>app.modules.ts</strong>
<strong>app.component.html</strong>
<strong>loader.component.html</strong>
<strong>loader.component.ts</strong>
<strong>loader.service.ts</strong>
<strong>A method in some service that does an AJAX call</strong>
The problem is that the loader never gets shown, because
is never set to
. The console output:
So the subscription to the loaderService, that changes the value of
in loader.component.ts only gets called once, when initializing the component. But as far as I understand how <strong>BehaviorSubject</strong> should work, it should be called, whenever
changes. Why not? What am I doing wrong?
This question is related to <a href="https://stackoverflow.com/questions...ime-data-recieved-from-the-server-in-angular2">how to show a spinner till the time data recieved from the server in angular2</a> but not a duplicate (as I want to do it with a reusable component) and <a href="https://stackoverflow.com/questions...js-behaviorsubject-subscribe-call-not-working">Angular 2 + RxJS BehaviorSubject subscribe call not working</a> (Though I don't see any difference between my code and the accepted answer. Did I miss something?)
I basically followed this tutorial <a href="https://hassantariqblog.wordpress.c...-spinner-as-service-in-angular-2-application/" rel="nofollow noreferrer">https://hassantariqblog.wordpress.c...-spinner-as-service-in-angular-2-application/</a>
Here's some of my code:
<strong>app.modules.ts</strong>
Code:
import {AppComponent} from './app.component';
import {AppRoutingModule} from './app-routing.module';
import {SomeComponent} from './some.component';
import {LoaderComponent} from './loader/loader.component';
import {LoaderService} from './loader/loader.service';
@NgModule({
declarations: [
AppComponent,
LoaderComponent,
SomeComponent
],
imports: [
BrowserModule,
NoopAnimationsModule,
AppRoutingModule
],
providers: [
LoaderService
],
bootstrap: [AppComponent]
})
export class AppModule {
}
<strong>app.component.html</strong>
Code:
<router-outlet></router-outlet>
<app-loader></app-loader>
<strong>loader.component.html</strong>
Code:
<div class="loader" *ngIf="isLoading"></div>
<strong>loader.component.ts</strong>
Code:
import {Component, OnInit} from '@angular/core';
import {LoaderService} from './loader.service';
@Component({
selector: 'app-loader',
templateUrl: 'loader.component.html',
providers: [LoaderService]
})
export class LoaderComponent implements OnInit {
isLoading: boolean;
constructor(private loaderService: LoaderService) {
}
ngOnInit() {
this.loaderService.status.subscribe((val: boolean) => {
this.isLoading = val;
});
}
}
<strong>loader.service.ts</strong>
Code:
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
@Injectable()
export class LoaderService {
public status: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
display(value: boolean) {
console.log('LoaderService.display ' + value);
this.status.next(value);
}
}
<strong>A method in some service that does an AJAX call</strong>
Code:
constructor(private http: Http, private loaderService: LoaderService) {
}
getSomeStuff(): Observable<SomeItem[]> {
// show the loading spinner
this.loaderService.display(true);
const content = this.http.get(this.apiUrl)
.map(this.extractData);
content.subscribe(
() => {
// hide the loading spinner
this.loaderService.display(false);
}
);
return content;
}
The problem is that the loader never gets shown, because
Code:
isLoading
Code:
true
Code:
LoaderComponent subscription false
LoaderService.display true
LoaderService.display false
So the subscription to the loaderService, that changes the value of
Code:
isLoading
Code:
LoaderService.status