Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dynamically get the values from Object Type and implement in Expansion panel Angular material?

Scenario:

Displaying the expansion panel name and content Dynamically using Angular material expansion panel using JSON.

Issue:

I able to place the Panel name Dynamically but for the content, I need to check the JSON in that I have a type key so based on type I need to push that particular functionality that particular div.

JSON:

[{
          module: "Person Details",
          type: 'table',
          moduleData: [
            {
              "firstName":"MaxRunner",
              "ID":"12345",
            }
          ]
        },
        {
          module: "Current Location",
          type: 'horizontal-stepper',
          CurrentData: [
            {
              "step":1,
              "description":"Philips",
              "status":true
            },
            {
              "step":2,
              "description":"Philips",
              "status":true
            },
            {
              "step":3,
              "description":"Philips",
              "status":false
            }
          ]
        }
      ];

here based on type key and I am pushing the moduledata key to the div present what I did was like I manually gave the key names but suppose in future in future if I have objects then I manually cannot set each name in div so is there any dynamically way to do this?

what I did

<div  *ngIf="module.type==='table'">
        <div *ngFor="let moduleKey of getKeys(module.moduleData[0])">
            <div > {{ moduleKey }} </div>
            <div> {{module.moduleData[0][moduleKey]}} </div>
        </div>
    </div>

<div style="border-bottom:0;" *ngIf="module.type==='horizontal-stepper'">   
    <div [ngClass]="'col-xs-3' + getStatusClass(step, index, module.CurrentData)" *ngFor="let step of module.CurrentData; let index = index">
      <div><div class="progress-bar"></div></div>
      <div >{{step.step}}</div>
      <div class="bs-wizard-info text-center" *ngIf="isActive(step.status, index, module.CurrentData)">{{step.description}}</div>
    </div>
    </div>

IN the code currently, I am implementing a manual way like giving the key name "module.CurrentData"

here I don't want to give name manually like "getStatusClass(step, index, module.CurrentData)"

Here is my stackblitz.

like image 530
Madpop Avatar asked Jul 05 '20 17:07

Madpop


2 Answers

Here is the updated (generic) version: StackBlitz

  • I have Updated the data to be more generic by adding data property instead of different property name for different types.

Here is the data look like now:

this.data = [{
          module: "Person Details",
          type: 'table',
          data: [
            {
              "firstName":"MaxRunner",
              "ID":"12345",
            }
          ]
        },
        {
          module: "Current Location",
          type: 'horizontal-stepper',
          data: [
            {
              "step":1,
              "description":"Philips",
              "status":true
            },
            {
              "step":2,
              "description":"Philips",
              "status":true
            },
            {
              "step":3,
              "description":"Philips",
              "status":false
            }
          ]
        }
      ];
  • I have updated the template code and now you only need to pass data instead of different names for different types.
<mat-accordion>
    <mat-expansion-panel *ngFor="let module of data">
        <mat-expansion-panel-header>
            {{module.module}}
        </mat-expansion-panel-header>

        <div  *ngIf="module.type==='table'">
            <div *ngFor="let moduleKey of getKeys(module.data[0])">
                <div > {{ moduleKey }} </div>
                <div> {{module.data[0][moduleKey]}} </div>
            </div>
        </div>

        <div style="border-bottom:0;" *ngIf="module.type==='horizontal-stepper'">   
            <div [ngClass]="'col-xs-3' + getStatusClass(step, index, module.data)" *ngFor="let step of module.data; let index = index">
              <div><div class="progress-bar"></div></div>
              <div >{{step.step}}</div>
              <div class="bs-wizard-info text-center" *ngIf="isActive(step.status, index, module.data)">{{step.description}}</div>
            </div>
        </div>

    </mat-expansion-panel>
like image 182
Johar Zaman Avatar answered Nov 14 '22 20:11

Johar Zaman


I am not sure this will help you. But in angular, there is a way to iterate over the key-value pairs using keyValuePipe. With this, you will get the key without hardcoding. For example,

<ng-container *ngFor="let module of modules">
  <div *ngFor="let moduleKey of module|keyvalue">
   <!--you can have dynamic key such as moduledata|currentData etc-->
</div>
</ng-container>
like image 24
gaurav soni Avatar answered Nov 14 '22 21:11

gaurav soni