Angular: how to test for a value in the template after an observable comes back

Viewed 32

I have a code in ngAfterInit() that subscribes to a post call to a server. The server takes X milliseconds and returns an object with an array of contacts.

These contacts should then be displayed in the HTML template as rows via *ngFor. If a contact is of type 3, an extra dropdown should be displayed on that row.

I have a timing issue though. It seems that the HTML template gets generated before the subscription result comes back and the object's contacts are set. The dropdowns do not show, regardless of whether type is 3 or not.

See the code below:

TYPESCRIPT:

  ngAfterViewInit(): void {
    //Personal Info
    this.individualService.individual$
      .pipe(takeUntil(this.destroy$))
      .subscribe((individual: PersonalInfo) => {
        this.personalInfo = new PersonalInfo(individual);
      });

HTML:

      <!-- the personalInfo object is received asyncronously -->
      <div *ngFor="let contact of personalInfo.communication; let i = index">
        <mat-form-field>
          <mat-label>TYPE</mat-label>
          <mat-select
            #matSelectComType
            [(ngModel)]="contact.type"
            name="{{ 'contactType' + i }}">
            <mat-option [value]="contact.type">{{getComTypeLabel(contact.type!)}}</mat-option>
            <ng-container *ngFor="let comType of filterContactTypes(contact.type!)">
              <mat-option [value]="comType.type">{{ comType.desc }}</mat-option>
            </ng-container>
          </mat-select>
        </mat-form-field>

          <mat-form-field>
            <mat-label>
                {{getComTypeLabel(matSelectComType.value) | uppercase}}
            </mat-label>
            <input
              matInput
              type="text"
              [(ngModel)]="contact.value"
              name="{{ 'contactValue' + i }}"
              required
              #contactValue="ngModel"
              [pattern]="getPattern(contact.type)"
            />
          </mat-form-field>

        <!-- cell network - problem here with *ngIf -->
          <mat-form-field *ngIf="contact.type === 3">
            <mat-label>NETWORK PROVIDER</mat-label>
            <mat-select 
              #matSelectNetworkType 
              [(ngModel)]="contact.networkType" 
              name="{{ 'networkType' + i }}"
              #networkType="ngModel">
              <mat-option *ngFor="let network of allNetworks" [value]="network.desc">
                {{ network.desc }}
              </mat-option>
            </mat-select>
          </mat-form-field>
      </div>
1 Answers

Since you are saying "I have a timing issue though. It seems that the HTML template gets generated before the subscription result comes back and the object's contacts are set." try setting a flag this.isSubscriptionResult = true once the subscription response comes and in the html check the flag value like wrap your code inside

<ng-container *ngIf="isSubscriptionResult"><div *ngFor="let contact of personalInfo.communication; let i = index">...your code</ng-container>

This maybe a workaround, but you can definitely give a try.

Related