2

I am using "ngx-spinner": "8.1.0", spinner shows up in tap() inside method for getting data from server.Spinner shows up but when trying to hide it on finalize() is not being hide at all. Any hint where might be the problem? Data from server are received and correctly displayed on view.

//component.ts


  ngAfterViewInit() {
    this.subscriptions.add(
      this.organizationsService.organizations$
        .pipe(
          tap(() => {
            this.spinnerService.showLoader();
          }),
          finalize(() => {
            this.spinnerService.hideLoader();
          }),
          takeUntil(this.destroySubject))
        .subscribe(response => {
          console.log('OUTPUT: OrganizationsListComponent -> ngAfterViewInit -> response', response);
          this.cachedFacts = this.cachedFacts.concat(response);
          if (!this.searchService.search.value.length) {
            this.dataSource.data = this.cachedFacts as IOrganizations[];
            this.dataSource.sort = this.sort;
          } else {
            this.dataSource.data = response as IOrganizations[];
            this.cachedFacts = [];
          }
          this.filterSelectObj.filter((o) => {
            o.options = this.getFilterObject(this.dataSource.data, o.columnProp);
          });
        }, (error) => {
          this.errorService.handleError(error);
        })
    );

  }

service.ts

this.organizations$ = combineLatest([this.pageSubject, this.searchService.search]).pipe(
      tap(([page, searchTerm]) => { console.log('search and page number', page, searchTerm); }),
      switchMap(([page, searchTerm]) => {
        let params: HttpParams;
        if (!searchTerm.length) {
          params = new HttpParams()
            .set('_page', page.toString());
        } else {
          params = new HttpParams()
            .set('q', searchTerm);
        }
        const apiUrl = this.http.get<IOrganizations[]>(`${this.apiUrl}`, { observe: 'response', params });
        return apiUrl.pipe(
          map((result) => {
            const totalCount = result.headers.get('x-total-count');
            this.totalOrganizationsCount.next(totalCount);
            this.cachedOrganizationsList.next(result.body);
            return result.body;
          })
        );
      })
    );

spinner.service.ts

@Injectable()
export class SpinnerService {
  constructor(private spinnerService: NgxSpinnerService) { }

  public showLoaderSubject = new BehaviorSubject<boolean>(false);

  showLoader() {
    this.showLoaderSubject.next(true);
    this.spinnerService.show();
  }

  hideLoader() {
    this.showLoaderSubject.next(false);
    this.spinnerService.hide();
  }
}

spinner.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SpinnerComponent } from './spinner.component';
import { NgxSpinnerModule, NgxSpinnerService } from 'ngx-spinner';
import { SpinnerService } from '@shared/services/spinner.service';
import { AngularMaterialModule } from '@app/angular-material/angular-material.module';

@NgModule({
  imports: [
    CommonModule,
    NgxSpinnerModule,
    AngularMaterialModule
  ],
  declarations: [SpinnerComponent],
  exports: [SpinnerComponent],
  providers: [SpinnerService, NgxSpinnerService]
})
export class SpinnerModule { }

Thanks for any hint

camel
  • 1,233
  • 2
  • 12
  • 18

1 Answers1

0

RxJS finalize operator will only be triggered when the source observable completes or errors out. Seeing that your observable organizations$ holds an observable from combineLatest function, it probably isn't completed. So instead of using finalize you could hide the spinner inside the subscription.

Try the following

ngAfterViewInit() {
  this.subscriptions.add(
    this.organizationsService.organizations$.pipe(
      tap(() => this.spinnerService.showLoader()),          // <-- no `finalize` here
      takeUntil(this.destroySubject)
    ).subscribe(response => {
        console.log('OUTPUT: OrganizationsListComponent -> ngAfterViewInit -> response', response);
        this.cachedFacts = this.cachedFacts.concat(response);
        if (!this.searchService.search.value.length) {
          this.dataSource.data = this.cachedFacts as IOrganizations[];
          this.dataSource.sort = this.sort;
        } else {
          this.dataSource.data = response as IOrganizations[];
          this.cachedFacts = [];
        }
        this.filterSelectObj.filter((o) => {
          o.options = this.getFilterObject(this.dataSource.data, o.columnProp);
        });

        this.spinnerService.hideLoader();         // <-- hide the spinner here
      }, (error) => {
        this.errorService.handleError(error);
      })
  );
}
ruth
  • 29,535
  • 4
  • 30
  • 57
  • nope, I tried it before and if I move this.spinnerService.hideLoader(); to subscribe then loader is not shown at all even if I add some long delay in the organizationsService service – camel Sep 18 '20 at 12:33