0

I am trying to show a spinner on my application while the data is loaded fully. So what I did is subscribe to the web service call. I have a variable called IsBusy which is set to True before I make the service call. Upon completion of the web service call I am setting IsBusy to false.

In my html I am using this IsBusy to show/hide my spinner. Right now it does not display spinner at all. Below is my html and typescript code.

<div id="surgeryRequestFormContainer" class="container-fluid">

        <div *ngIf="isBusy" class="loading">
            <img  src="http://thinkfuture.com/wp-content/uploads/2013/10/loading_spinner.gif"  />
        </div>
     <div class="row">
                <div class="form-group col-sm-12">
                    <button kendoButton (click)="btnPrevious()">Previous</button>
                    <button kendoButton (click)="btnNext()">Next</button>
                    <button kendoButton (click)="btnSaveForLater()">Save For Later</button>

                </div>
            </div>

I researched before posting and read somewhere that I may need to import ChangeDetectorRef from '@angular/core'. I did that and instantiated ChangeDetectorRef as cd in my constructor.

 ngOnInit(): void {


        this.isBusy = true;
        console.log("before the subscribe " + this.isBusy);

        this.route.params
            .switchMap((params: Params) => this._RequestFormService.getRequestById(+params['id']))
            .subscribe(
            data => this.Model = data,
            error => console.log("Error", error),
            () => this.isBusy = false);
        this.isBusy = false;
        console.log(this.isBusy);
        this.cd.detectChanges(); // marks path

    }

I am not sure what I need to do in order to show/hide my spinner div tag.

David L
  • 32,885
  • 8
  • 62
  • 93
HereToLearn_
  • 1,150
  • 4
  • 26
  • 47
  • 1
    Move `this.isBusy = false` inside of your subscribe "next" callback (where you are currently doing `this.Model = data`. – adam-beck Apr 24 '17 at 15:58
  • just as adam-beck said. Check this one, where the same problem is with console.log outside callback: http://stackoverflow.com/questions/43055706/how-do-i-return-the-response-from-an-observable-http-async-call-in-angular2 – AT82 Apr 24 '17 at 15:59
  • 1
    Possible duplicate of [How do I return the response from an Observable/http/async call in angular2?](http://stackoverflow.com/questions/43055706/how-do-i-return-the-response-from-an-observable-http-async-call-in-angular2) – n00dl3 Apr 24 '17 at 16:01

1 Answers1

2

What's happening is the Observable chain is making an asynchronous call. So basically the code execution does not wait and the call to this.isBusy = false after the chain is called almost immediately after the line this.isBusy = true. Only afterwards does the call to the service complete. But again, by this point, your spinner has already been closed.

Instead what you should do is move that call inside of your observable chain.

this.isBusy = true;

this.route.params
    .switchMap((params: Params) => this._RequestFormService.getRequestById(+params['id']))
    .subscribe(
        data => { 
            this.Model = data;
            this.isBusy = false;
        },
        error => console.log("Error", error),
        () => this.isBusy = false);

If you are familiar with setTimeout this is essentially what you have done with your code.

console.log('setting the value to true');

setTimeout(function() {
  console.log('setting the value to false');
}, 1000);

console.log('setting the value to false');

Not to add to any confusion but Observables are not inherently asynchronous. And I don't believe the the "finally" callback in the subscribe will be called here as the Observable never "ends".

adam-beck
  • 5,659
  • 5
  • 20
  • 34