2
votes

In my store I have isLoading: boolean value which is false and changed to true when request to server starts and after respose or on error it changed back to false. I select it in container class and pass to component as property like this:

@Component({
  template: `<some-component [isLoading]="isLoading"></some-component>`
})

class SomeContainer() {
  private isLoading: Observable<boolean>;
  constructor(private store: Store<IStore>) {
    this.isLoading = store.select(isLoadingSelector);
  }
}

And I would like to use it for some conditional content:

class SomeComponent {
  @Input() private isLoading: Observable<boolean>;
  ...
}

<div>
  <span *ngIf="isLoading">Loading</span>
  <span *ngIf="!isLoading">Some data</span>
</div>

but isLoading is Observable and I have to get boolean value for expected working of this logic. The solution I found is getting value in class like this:

private ngOnInit():void {
  this.isLoading.subscribe((value) => this.isLoadingBoolean = value);
}

and use isLoadingBoolean in template.

But it looks tricky. Is there better way to solve this issue (maybe is way to use async pipe with *ngIf)?

1
did you try *ngIf="!(isLoading | async)"? - chrigu

1 Answers

3
votes

You can use the async pipe in your SomeContainer:

@Component({
  template: `<some-component [isLoading]="isLoading | async"></some-component>`
})
class SomeContainer() {
  private isLoading: Observable<boolean>;
  constructor(private store: Store<IStore>) {
    this.isLoading = store.select(isLoadingSelector);
  }
}

And your SomeComponent can be simplified to use a boolean input:

@Component({
  template: `
    <div>
      <span *ngIf="isLoading">Loading</span>
      <span *ngIf="!isLoading">Some data</span>
    </div>
  `
})
class SomeComponent {
  @Input() private isLoading: boolean;
  ...
}

Typically, it's a good idea to deal with the observables in the containers so that the components can be 'dumb' - see "Presentational and Container Components".