0

Is there a way to refactor the typescript in this component as to not duplicate the code for each coverage line? This is an angular component with an ngFor in the HTML template, using a different "GroupsView" depending on context.

<div *ngFor="let benefitGroup of medicalBenefitsGroupsView;">
    
</div>
<div *ngFor="let benefitGroup of dentalBenefitsGroupsView;">
    
</div>
<div *ngFor="let benefitGroup of visionBenefitsGroupsView;">
    
</div>

Ideally I'd like to use benefitsGroupsView for all 3 but I'm having trouble figuring this out without moving the filter logic to the template.

    benefitGroups = benefitGroups
      .filter((x) => x.benefits.length)
      .sort((a, b) => a.benefitGroupName.localeCompare(b.benefitGroupName));

    const medicalBenefitGroups = benefitGroups.filter((group) => {
      return group.benefits.some((benefit) => benefit.coverageLineBenefits.some(b =>b .coverageLineId == 1));
    });

    const dentalBenefitGroups = benefitGroups.filter((group) => {
      return group.benefits.some((benefit) => benefit.coverageLineBenefits.some(b =>b .coverageLineId == 2));
    });

    const visionBenefitGroups = benefitGroups.filter((group) => {
      return group.benefits.some((benefit) => benefit.coverageLineBenefits.some(b =>b .coverageLineId == 3));
    });

    this.benefitsGroupsView = benefitGroups.map((group) => ({
      value: group.benefitGroupId,
      viewValue: group.benefitGroupName,
      checked: group.benefits.every(b => b.isDisplayable),
      coverageLineId: group.benefits[0].coverageLineBenefits[0].coverageLineId,
      benefits: group.benefits
        .sort((a, b) => a.benefitName.localeCompare(b.benefitName))
        .map((b) => ({
          value: b.benefitId,
          viewValue: b.benefitName,
          checked: b.isDisplayable,
          groupValue: group.benefitGroupId, 
        })),
    }));

    this.medicalBenefitsGroupsView = medicalBenefitGroups.map((group) => ({
      value: group.benefitGroupId,
      viewValue: group.benefitGroupName,
      checked: group.benefits.every(b => b.isDisplayable),
      benefits: group.benefits
        .sort((a, b) => a.benefitName.localeCompare(b.benefitName))
        .map((b) => ({
          value: b.benefitId,
          viewValue: b.benefitName,
          checked: b.isDisplayable,
          groupValue: group.benefitGroupId, 
        })),
    }));

    this.dentalBenefitsGroupsView = dentalBenefitGroups.map((group) => ({
      value: group.benefitGroupId, 
      viewValue: group.benefitGroupName,
      checked: group.benefits.every(b => b.isDisplayable),
      benefits: group.benefits
        .sort((a, b) => a.benefitName.localeCompare(b.benefitName))
        .map((b) => ({
          value: b.benefitId,
          viewValue: b.benefitName,
          checked: b.isDisplayable,
          groupValue: group.benefitGroupId, 
        })),
    }));

    this.visionBenefitsGroupsView = visionBenefitGroups.map((group) => ({
      value: group.benefitGroupId,
      viewValue: group.benefitGroupName,
      checked: group.benefits.every(b => b.isDisplayable),
      benefits: group.benefits
        .sort((a, b) => a.benefitName.localeCompare(b.benefitName))
        .map((b) => ({
          value: b.benefitId,
          viewValue: b.benefitName,
          checked: b.isDisplayable,
          groupValue: group.benefitGroupId, 
        })),
    }));

1 Answer 1

1

What we can do, and this is a very simplified variant is to leverage switchStatements in the html. So if I am understanding your desire correctly, given that each one of those groups is defined based on its coverageLineId property, we can just use that instead.

Then in our template, we display what we need based on the coverageLineId

<div *ngFor="let benefits of benefitsGroupsView">
  <ng-container [ngSwitch]="benefits.coverageLineId">

    <div *ngSwitchCase="1">div 1</div>
    <div *ngSwitchCase="2">div 2.</div>
    <div *ngSwitchCase="3">div 3</div>

  </ng-container>
</div>

One thing to note is that you will need to give it the data in a sorted fashion, so something simple like this sort((a, b) => a.coverageLineId > b.coverageLineId ? 1 : -1) will be the sorting function for ascending order. If you don't provide the data in a sorted manner then it will display it as it comes. Meaning that if your benefit goes: medical => dental => medical it will display it as such.

Edit: Documentation/further reading: https://angular.io/api/common/NgSwitchCase

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.