Search code examples
htmlangularredundancy

Remove business logic from html and avoid redundance code Angular


I wrote this code in HTML, which is very very long. I used ngSwitch for 3 cases and in the default case I have 4 different small cases. All of these cases used the same structure of icon. How could I make my HTML shorter? How could I remove the business logic from HTML?

The rule to show different icons is:

Serviceflag (boolean) > warnflag (boolean) > serviceflag (boolean) > timekey(number)

For Example: If the code includes all of them then the icon of Serviceflag should be shown. If the code includes warnflag and timekey then the icon of warnflag should be shown.

   
<ng-template #defaultModalHeaderTemplate>
  <app-device-status-information
    *ngIf="status"
    [statusInformation]="status"
  ></app-device-status-information>
  <app-device-status-information
    *ngIf="information"
    [statusInformation]="information"
  ></app-device-status-information>
</ng-template>
<div
  class="fit-h fit-v d-flex d-col"
  [ngSwitch]="
    !(status.warnFlag && !status.serviceFlag && !status.errorFlag) ||
    !(status.errorFlag && !status.serviceFlag)
  "
>
  <div
    style="background-color: rgba(241, 90, 34, 0.1)"
    class="fit-h fit-v d-flex d-col"
    *ngSwitchCase="status.warnFlag && !status.serviceFlag && !status.errorFlag"
  >
    <div class="row" style="padding: 36px 0px 24px 24px">
      <div class="col-sm-2">
        <ng-container>
          <i
            c8yicon="warning"
            class="text-warning dlt-c8y-icon-warning"
            style="font-size: 80px"
            ng-reflect-c8y-icon="warning"
          ></i>
        </ng-container>
      </div>
      <div class="col-sm-10">
        <ng-container *ngTemplateOutlet="defaultModalHeaderTemplate"></ng-container>
      </div>
    </div>
  </div>

  <div
    *ngSwitchCase="status.errorFlag && !status.serviceFlag"
    style="background-color: rgba(217, 30, 24, 0.1)"
    class="fit-h fit-v d-flex d-col"
  >
    <div class="row" style="padding: 36px 0px 24px 24px">
      <div class="col-sm-2">
        <ng-container style="background-color: bg-dark-warning">
          <i
            c8yicon="exclamation-circle"
            class="text-danger dlt-c8y-icon-exclamation-circle"
            style="font-size: 80px"
            ng-reflect-c8y-icon="exclamation-circle"
          ></i>
        </ng-container>
      </div>
      <div class="col-sm-10">
        <ng-container *ngTemplateOutlet="defaultModalHeaderTemplate"></ng-container>
      </div>
    </div>
  </div>

  <div *ngSwitchDefault>
    <div class="row">
      <div class="col-sm-2" style="padding-left: 48px">
        <ng-container *ngIf="status.serviceFlag">
          <i
            c8yicon="wrench"
            class="text-complementary dlt-c8y-icon-wrench"
            style="font-size: 80px"
            ng-reflect-c8y-icon="wrench"
          ></i>
        </ng-container>

        <ng-container
          *ngIf="
            information.timeKey === 1 &&
            !status.warnFlag &&
            !status.serviceFlag &&
            !status.errorFlag
          "
        >
          <i
            c8yicon="check-circle"
            class="text-success dlt-c8y-icon-check-circle"
            style="font-size: 80px"
            ng-reflect-c8y-icon="check-circle"
          ></i>
        </ng-container>

        <ng-container
          *ngIf="
            (information.timeKey === 2 ||
              information.timeKey === 3 ||
              information.timeKey === 4 ||
              information.timeKey === 6) &&
            !status.warnFlag &&
            !status.serviceFlag &&
            !status.errorFlag
          "
        >
          <i
            c8yicon="stop-circle"
            class="text-info dlt-c8y-icon-stop-circle"
            style="font-size: 80px"
            ng-reflect-c8y-icon="stop-circle"
          ></i>
        </ng-container>

        <ng-container
          *ngIf="
            information.timeKey === 5 &&
            !status.warnFlag &&
            !status.serviceFlag &&
            !status.errorFlag
          "
        >
          <i
            c8yicon="exclamation-circle"
            class="text-muted dlt-c8y-icon-exclamation-circle"
            style="font-size: 80px"
            ng-reflect-c8y-icon="exclamation-circle"
          ></i>
        </ng-container>
      </div>
      <div class="col-sm-10">
        <ng-container *ngTemplateOutlet="defaultModalHeaderTemplate"></ng-container>
      </div>
    </div>
  </div>
</div>


Solution

  • Start by declaring getters in your typescript, while also reducing and factoring your logic

    
    get flagType(): 0 | 1 | 2 {
      // Adapt your logic here
      return this.status.errorFlag ? 0 : 
        this.status.warnFlag ? 1 : 
        this.status.serviceFlag ? 2 : null;
    }
    
    get bgColor(): string {
      // Again, adapt your colors here depending on the above
      return ['red', 'yellow', 'green'][this.flagType];
    }
    
    get icon() {
      // Again, adapt
      return ['error', 'warning', 'service'][this.flagType];
    }
    
    // Add every getter you need 
    

    Then, in your HTML, you can call it once, with the getters.

      <div
        [style.background-color]="bgColor"
        class="fit-h fit-v d-flex d-col"
      >
        <div class="row" style="padding: 36px 0px 24px 24px">
          <div class="col-sm-2">
            <ng-container>
              <i
                [c8yicon]="icon"
                class="text-{{ icon }} dlt-c8y-icon-warning"
                style="font-size: 80px"
              ></i>
            </ng-container>
          </div>
          <div class="col-sm-10">
            <ng-container *ngTemplateOutlet="defaultModalHeaderTemplate"></ng-container>
          </div>
        </div>
      </div>