I have an angular component:
import { Component, OnInit } from '@angular/core';
import { Hall } from 'src/app/models/hall.model';
import { HallService } from 'src/app/services/hall.service';
import { ActivatedRoute, Router } from '@angular/router';
import {City} from "../../models/city.model";
@Component({
selector: 'app-halls-list',
templateUrl: './halls-list.component.html',
styleUrls: ['./halls-list.component.css']
})
export class HallsListComponent implements OnInit {
Halls?: Hall[];
currentHall: Hall = {};
currentIndex = -1;
name = '';
placeqty='';
//cityid='';
cityid:any;
constructor(private hallService:HallService,private route: ActivatedRoute,private router: Router) { }
ngOnInit(): void {
this.retrieveHalls();
}
retrieveHalls(): void {
this.hallService.getAll()
.subscribe(
data => {
this.Halls = data;
console.log(data);
},
error => {
console.log(error);
});
}
refreshList(): void {
this.retrieveHalls();
this.currentHall = {};
this.currentIndex = -1;
}
setActiveHall(hall: Hall, index: number): void {
this.currentHall = hall;
this.currentIndex = index;
}
deleteHall(): void {
this.hallService.delete(this.currentHall.id)
.subscribe(
response => {
console.log(response);
this.router.navigate(['/halls']);
},
error => {
console.log(error);
});
}
}
It is getting data from a rest api that I previously wrote with spring boot. City id is a related column, so it is returning object with a name of a city and it's id. The console output is like this:
[
{
"id": 1,
"name": "TestHall",
"placeqty": 100,
"cityid": {
"id": 2,
"name": "Dnepr"
}
}
]
The id of a city and it's name is one. So in this object only one city can be returned. Now what I want is to display city's name but without id. Here is what I have so far in a template:
<div class="col-md-6">
<h4>Список залов</h4>
<ul class="list-group">
<li
class="list-group-item"
*ngFor="let hall of Halls; let i = index"
[class.active]="i == currentIndex"
(click)="setActiveHall(hall, i)"
>
{{ hall.name }}
<br>
кол-во мест: {{ hall.placeqty }}
<br>
<p>{{hall.cityid | json}}</p>
<div *ngFor="let item of hall.cityid | keyvalue;">
{{ item.key}} - {{ item.value }}
</div>
</li>
</ul>
</div>
<div class="col-md-6">
<div *ngIf="currentHall.id">
<h4>Зал</h4>
<div>
<label><strong>Название:</strong></label> {{ currentHall.name }}
<label><strong>Количество мест:</strong></label> {{ currentHall.placeqty }}
<label><strong>Город:</strong></label> {{ currentHall.cityid }}
</div>
<a class="badge badge-warning" routerLink="/cities/{{ currentHall.id }}">
Изменить
</a>
<div *ngIf="!currentHall">
<br />
<p>Выберите Зал...</p>
</div>
</div>
</div>
If i would use PHP I would do somethin like
echo $cityid[0]['name'];
without any loop. Is it posible in Angular? Or how I can solve it?
My model class:
export class Hall {
id?:any;
name?:string;
placeqty?:string;
cityid?:string;
}
Well. The unswer is very correct. In addition I will add my City model just in case someone will need this. It also worked this way in case of Angular 12, however it is my very first project on Angular and I have no idea how it would work on Angular 11 or lower. But still
export class City {
id?:any;
name?:string;
}
CodePudding user response:
To gather all comments to an answer instead...
So if you are receiving data like:
{
"id": 1,
"name": "TestHall",
"placeqty": 100,
"cityid": {
"id": 2,
"name": "Dnepr"
}
}
Your models need to first of all match, so they should be something like this:
interface Hall {
id: number;
name: string;
placeqty: number;
cityid: City;
}
interface City {
id: number;
name: string;
}
Now, for nested objects, you can use the safe navigation operator to safeguard null
or undefined
values. And to get the name of the city you just access that nested property with:
<p>{{ hall.cityid?.name }}</p>