Display different table based upon the different selection in angular using select tag

Viewed 479

I want to display the different tables in angular based upon the value that I am choosing from the select tag using ngFor directive. Right now I am doing this using some boolean variables and I am checking the condition using ngIf in html. You can refer my sample code which is shown below.

Here is my sample code:

component.html

<select class="form-control" [(ngModel)]="selectOption" (change)="getTables($event)">
        <option *ngFor="let item of optionsArr" [value]="item.slectedValue" >{{ item.slectedValue }} 
        </option>
</select>

<table class="table table-bordered" id="admin-table" *ngIf="adminText">
    <thead>
        <th>Check Me</th>
        <th>Sr. No</th>
        <th>ID</th>
        <th>Admin Name</th>
        <th>City</th>
    </thead>
    <tbody>
        <tr *ngFor="let admin of adminArr; let i = index">
            <td><input type="checkbox" name="chk1" id="chk1"></td>
            <td>{{ i+1 }}</td>
            <td>{{ admin.id }}</td>
            <td>{{ admin.name }}</td>
            <td>{{ admin.city }}</td>
        </tr>
    </tbody>
</table>
<table class="table table-bordered" *ngIf="employeeText">
    <thead>
        <th>Sr. No</th>
        <th>ID</th>
        <th>Employee Name</th>
        <th>City</th>
    </thead>
    <tbody>
        <tr *ngFor="let item of employeeArr; let i = index">
            <td>{{i+1}}</td>
            <td>{{item.id}}</td>
            <td>{{item.name}}</td>
            <td>{{item.city}}</td>
        </tr>
    </tbody>
</table>
<table class="table table-bordered" *ngIf="studentText">
    <thead>
        <th>Sr. No</th>
        <th>ID</th>
        <th>Student Name</th>
        <th>City</th>
    </thead>
    <tbody>
        <tr *ngFor="let item of studentArr; let i = index;">
            <td>{{i+1}}</td>
            <td>{{item.id}}</td>
            <td>{{item.name}}</td>
            <td>{{item.city}}</td>
        </tr>
    </tbody>
</table>

component.ts

  adminArr: any = [];
  employeeArr: any = [];
  studentArr: any = [];

  selectOption:any;
  adminText: boolean = false;
  employeeText: boolean = false;
  studentText: boolean = false;
  newValue:any;

  optionsArr:any = [
    {"id": 1, "slectedValue": "Admin"},
    {"id": 2, "slectedValue": "Employees"},
    {"id": 3, "slectedValue": "Students"}
  ]
getTables(event: any){
    let value = event.target.value;
    this.newValue = value;
    if(this.newValue === "Admin"){
        this.adminText = true;
        this.http.get(this.adminUrl).subscribe(data => {
        this.adminArr = data;
        this.adminArr.push(data);
      });
      console.log(this.adminArr);      
      this.employeeText = false;
      this.studentText = false;
    }
    else if(this.newValue === "Employees"){
        this.employeeText = true;
        this.http.get(this.stdUrl).subscribe(data => {
        this.employeeArr = data;
        this.employeeArr.push(data);
      });
      this.adminText = false;
      this.studentText = false;
    }
    else{
        this.studentText = true;
        this.http.get(this.stdUrl).subscribe(data => {
        this.studentArr = data;
        this.studentArr.push(data);
      });
      this.employeeText = false;
      this.adminText = false;
    }
    
  }

I think this approach is not suitable because if I have 10 values in my select tag then it is not a good coding practice. There must be some better way of doing the same. Can anyone can show me the correct way of doing this? Can anyone help me with the better solution?

NOTE: Right now I have not created any model class and service. That is why I am using http request in my component only.

1 Answers

So what you can try is something like creating a component for your table, let's call it <rando-table>

rando-table.component.html

<table class="table table-bordered">
<thead>
    <th>Sr. No</th>
    <th>ID</th>
    <th>Employee Name</th>
    <th>City</th>
</thead>
<tbody>
    <tr *ngFor="let item of items; let i = index">
        <td>{{i+1}}</td>
        <td>{{item.id}}</td>
        <td>{{item.name}}</td>
        <td>{{item.city}}</td>
    </tr>
</tbody>

rando-table.component.ts

// basic angular jazz
export class RandoTableComponent {
@Input("items") items: any[] = [];
..
..
..
}

This will allow you to have a single table component to which you only need to pass an array that it will render the data for. The array that you are getting in component.ts's http calls can be assigned to an array that is defined once in your component, i.e something like dataArray and after every api call, you just add your response to this dataArray. Your rando-table component's items will keep changing as you change it in the parent.

I'd suggest referring to some of the official tutorials (like Tour of Heroes) to really get the hang of what is going here. It's basically applying some basic rules of DRY. Good luck with Angular :D

Related