[Fixed] Angular verify value inside an array from the result another array

Issue

I’m trying to check a value inside an array, from the result of another array, and put a key inside the object so that I can make an ngfor on my screen and bring those values, but I’m not getting it. I need to create the volumes key inside the server array, the getVolumes endpoint returns me an object array containing the attachments key and inside it the server_id key, where is the server id that that volume is located on. I need to bring only the volumes that contain a value for the name key, but the result is an empty array. Can you help me?

My code

  ngOnInit(): void {
    forkJoin(this.serverService.getServer(), 
    this.storage.getVolumes())
    .pipe(takeWhile(() => this.alive))
    .subscribe(([servers, volumes]) => {
      this.volumes = volumes;
      this.servers = servers.map((server) => ({
        ...server,
        volumes: this.volumes.map((volume) => {
          volume['attachments'].map((volumeId) => {
            console.log(volumeId)
            volumeId['server_id'] === server.id ? volumeId : 'None';
            console.log(this.servers)
          })
        })
      }))
    })
  }

My html code:

<ng-container *ngFor="let volume of volumes">
                <tr *ngIf="volume?.name.length > 2" (click)="selectVolume = volume">
                  <td>  
                    <div class="user-info">
                      <div class="user-info__img">
                        <img src="./assets/img/storages.svg" alt="UserImg">
                      </div>
                      <div class="user-info__basic">
                        <h5 class="mb-0">{{volume.name}}</h5>
                      </div>
                    </div>
                  </td>
                  <td >{{volume.size}} GB</td>

                  <td>
                    <span *ngFor="let attachedVolume of servers.volumes">
                      {{attachedVolume.name}}
                    </span>
                  </td>
</ng-container>

My Response from Volume API:

{
      "id": "939b1432-13f7-41ff-b9d2-908b25499c99",
      "name": "",
      "size": 10,
      "status": "in-use",
      "volume_type": "__DEFAULT__",
      "attachments": [
        {
          "id": "939b1432-13f7-41ff-b9d2-908b25499c99",
          "server_id": "1879f47f-1c5e-464b-bb76-e7cc13ef426e",
          "attachment_id": "5749f842-5dff-48ac-ac57-2a6bfb806ad5",
          "volume_id": "939b1432-13f7-41ff-b9d2-908b25499c99",
          "device": "/dev/vda",
        }
      ]
    },
    {
      "id": "bd91e685-bdd4-4bb8-b25d-18e91f458fb8",
      "name": "Test01",
      "size": 20,
      "status": "in-use",
      "volume_type": "__DEFAULT__",
      "attachments": [
        {
          "id": "bd91e685-bdd4-4bb8-b25d-18e91f458fb8",
          "server_id": "1879f47f-1c5e-464b-bb76-e7cc13ef426e",
          "attachment_id": "f4cd9033-dd6e-4d47-88a7-904c267f162f",
          "volume_id": "bd91e685-bdd4-4bb8-b25d-18e91f458fb8",
          "device": "/dev/vdc"
        }
      ]
    },
    {
      "id": "97b800c5-1061-4a38-b7ec-c4528f248f72",
      "name": "",
      "size": 20,
      "status": "in-use",
      "volume_type": "__DEFAULT__",
      "attachments": [
        {
          "id": "97b800c5-1061-4a38-b7ec-c4528f248f72",
          "server_id": "b9c7e32a-bf99-4250-83cb-13523f9c1604",
          "attachment_id": "c0cd7598-69ba-4ce8-8407-aef68219a00d",
          "volume_id": "97b800c5-1061-4a38-b7ec-c4528f248f72",
          "device": "/dev/vda",
        }
      ]
    },

My Server API Response

{
      "id": "1879f47f-1c5e-464b-bb76-e7cc13ef426e",
      "name": "olakital",
      "flavor": {
        "id": "21f46a72-7f4f-40c5-9f1f-0100fadbc226",
        "disk": "10",
        "ram": "4000",
        "swap": "",
        "vcpus": "4"
      }
    },
    {
      "id": "b9c7e32a-bf99-4250-83cb-13523f9c1604",
      "name": "teste01",
      "flavor": {
        "id": "59fc4d83-156d-4aa6-84a7-ea1c90d0fde5",
        "disk": "20",
        "ram": "8",
        "swap": "200",
        "vcpus": "4"
      }
    }

Solution

If I really understand your request, you can filter for valid volumes (volumes with a not empty name) which have server_id as attachment. Try this code:

ngOnInit(): void {
    forkJoin(this.serverService.getServer(), 
    this.storage.getVolumes())
    .pipe(takeWhile(() => this.alive))
    .subscribe(([servers, volumes]) => {
      this.volumes = volumes;
      this.servers = servers.map((server) => ({
        ...server,
        volumes: volumes.filter(volume => volume.name && volume.attachments.some(attachment => attachment.server_id == server.id))

      }))
    })
  }

HTML: 

<span *ngFor="let server of servers "> 
    <span *ngFor="let attachedVolume of server.volumes "> 
         {{attachedVolume.name}}
    </span>
</span>

UPDATE:
What if you switch to this? in this way you can check directly which server the storage is allocated to:

ngOnInit(): void {
    forkJoin(this.serverService.getServer(), 
    this.storage.getVolumes())
    .pipe(takeWhile(() => this.alive))
    .subscribe(([servers, volumes]) => {
      this.volumes = volumes.map(volume => ({
          ...volume,
          servers: servers.filter(server => volume.attachments.some(attachment => attachment.server_id == server.id))
       })),
      this.servers = servers;
    })
  }

HTML:

<ng-container *ngFor="let volume of volumes">
    <tr *ngIf="volume?.name.length > 2" (click)="selectVolume = volume">
        <td>  
            <div class="user-info">
                <div class="user-info__img">
                    <img src="./assets/img/storages.svg" alt="UserImg">
                </div>
                <div class="user-info__basic">
                    <h5 class="mb-0">{{volume.name}}</h5>
                </div>
            </div>
        </td>
        <td >{{volume.size}} GB</td>

        <td>
            <span *ngFor="let server of volume.servers">
              {{server.name}}
            </span>
        </td>
</ng-container>

Leave a Reply

(*) Required, Your email will not be published