3

I have a stepper which is conditioned by a single observable

<ng-container *ngIf="!(categoriesLoading$ | async); else loading">
  <mat-vertical-stepper *ngIf="categories$ | async as categories">
    <mat-step>
      <categories-form [categories]="categories"></categories-form>
    </mat-step>
  </mat-vertical-stepper>
</ng-container>

now I would like to add the conditioning of another observable qualifications$

Something like that:

<ng-container *ngIf="!(categoriesLoading$ | async); else loading">
  <mat-vertical-stepper *ngIf="categories$ | async as categories">
    <mat-step>
      <categories-form [categories]="categories"></categories-form>
    </mat-step>
    <mat-step>
      <qualifications-form [qualifications]="qualifications"></qualifications-form>
    </mat-step>
  </mat-vertical-stepper>
</ng-container>

in the controller:

categories$: Observable<Array<Category>>;
categoriesLoading$: Observable<boolean>;
qualifications$: Observable<Array<Qualification>>;
qualificationsLoading$: Observable<boolean>;

how can I do this properly?

4
  • something like this? - I'm not quite sure what you mean: *ngIf="!(categoriesLoading$ | async) && (qualificationsLoading$ | async); else loading" Are you looking to extend the condition on line 1? or extending the for loop of line 2? (2nd example) Commented Feb 26, 2019 at 9:42
  • @JonasPraem I would like to have the same result of the first example by adding qualifications$ observable Commented Feb 26, 2019 at 9:47
  • 2
    I would rethink the design of that.. you might run into race conditions. I would chain those observables with .pipe(), then wait for the final one to resolve and act upon that final result, not on 2 at the same time. Commented Feb 26, 2019 at 9:53
  • 2
    stackoverflow.com/questions/44855599/… Commented Feb 26, 2019 at 12:48

1 Answer 1

3

You can have a look at the Rxjs zip combination operator which might help you.

https://www.learnrxjs.io/operators/combination/zip.html

https://rxmarbles.com/#zip

In your controller, you can create a new observable like:

combined$: Observable<{ categories: Array<Category>, qualifications: Array<Qualification>}> = zip(
    this.categories$,
    this.qualifications$,
    (categories: Array<Category>, qualifications:Array<Qualification>) => { 
        return { categories, qualifications };
    }
);

Which will combine the emitted values, then you can use it to get the combined values:

<ng-container *ngIf="!(categoriesLoading$ | async); else loading">
  <mat-vertical-stepper *ngIf="combined$ | async as combined">
    <mat-step>
      <categories-form [categories]="combined.categories"></categories-form>
    </mat-step>
    <mat-step>
      <qualifications-form [qualifications]="combined.qualifications"></qualifications-form>
    </mat-step>
  </mat-vertical-stepper>
</ng-container>

Also you can use zip to have your loading observables wait for each other:

combinedLoading$: Observable<boolean> = zip(
    this.categoriesLoading$,
    this.qualificationsLoading$,
    (categoriesLoading: boolean, qualificationsLoading: boolean) => { 
        return categoriesLoading && qualificationsLoading;
    }
);
Sign up to request clarification or add additional context in comments.

1 Comment

I have this error: Type 'OperatorFunction<boolean, boolean>' is missing the following properties from type 'Observable<boolean>': _isScalar, source, operator, lift, and 6 more. where do you come from?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.