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>