[Fixed] Angular – Repeat value on select Option

Issue

I have a select, where the user’s servers are rendered. Each server has several security groups. I need to show the user on select, only the server that does not have that security group. However, in my select, it is repeating the name of the server for each different security group.

Example: I have the server test01 it has the security groups: novo09, default, relow.

When I select the security group hello01, I want to show the server test01 only once in select, and not 2 times, it is showing 2 times because I have 2 groups already included in server = novo09, relow.

server payload:

{id: "b9c7e32a-bf99-4250-83cb-13523f9c1604", name: "test01", flavor: {…}, securityGroups: [{name: 'relow'}, {name: 'Novo09'} ]}

My component code:

public selectedGroupName: string = '';
ngOnInit(): void {

    let counter = 0;
    forkJoin(
      this.serverService.getServer(),
      this.securityGroupService.getSecurityGroups())
      .pipe(takeWhile(() => this.alive),
      concatMap((data) => {
        this.servers = data[0].map((item) => ({
          ...item,
          securityGroups: this.serverService.getServerById(item.id)
            .pipe(map(server => server["security_groups"]))
        }))
        this.securityGroups = data[1].map((item) => ({
          ...item,
          expanded: false,
        }))
        return this.servers.map((server) => server.securityGroups);
      }), concatMap(items => items))
      .subscribe((data: any) => {
        this.servers[counter].securityGroups = data.filter(group => group.name !== 'default');
        counter++;
    })

    this.form = this.formBuilder.group({
      server: new FormControl('')
    })
  }
public openAttachModal(content, securitGroupName: string) {
    this.selectedGroupName = securitGroupName;
}

My Html code:


      <ng-container *ngFor="let group of securityGroups">
 <div class="user-info__basic">
                <h5 class="mb-0">{{group.name}}</h5>
              </div>
 <button type="button" class="btn btn-primary" ngbTooltip="Attach Group" triggers="hover"
              (click)="openAttachModal(attachModal, group.name)"><i class="fas fa-plus"></i></button>
</ng-container>

 <ng-container *ngFor="let server of servers">
          <ng-container *ngFor="let secGroup of server.securityGroups">
            <ng-container *ngIf="secGroup.name !== selectedGroupName">
              <option [value]="server.id">
                {{server.name}}
              </option>
            </ng-container>
          </ng-container>
          <ng-container *ngIf="server.securityGroups.length == 0">
            <option [value]="server.id">
              {{server.name}}
            </option>
          </ng-container>
        </ng-container>

image result of select
https://imgur.com/7K2G7HF

Solution

When the user selects the security group, you could trigger an event to extract the list of servers where that security group is not present. Something like:

const servers = servers.filter(server => !server.securityGroups.find(secGroup => secGroup.id === selectedSecurityGroup.id));
// Where selectedSecurityGroup is the security group the user selected

And you could avoid adding a server twice:

servers = servers.filter((server, index, self) => self.indexOf(server) === index);

This filter will keep only the first instance of each server.

Leave a Reply

(*) Required, Your email will not be published