how to iterate with *ngFor through nested object JSON - html

I have a nested object JSON file which looks something like this:
"8": {
"age": "Grand Masters",
"gender": "Women",
"division": "Club",
"year_placements": {
"2017": {
"year": 2017,
"event_id": "53522846-5039-11eb-8917-080027315160",
"event_season_id": "d62f237c-5040-11eb-8917-080027315160",
"event_name": "USA Ultimate Masters Championships",
"event_location": "Aurora, Colorado",
"placements": {
"1": {
"d62c24e9-5040-11eb-8917-080027315160": {
"team": "Boston",
"team_location": "Boston, Massachusetts",
"team_season_id": "d62c24e9-5040-11eb-8917-080027315160",
"event_team_placement_id": 5411
}
},
"2": {
"d6333181-5040-11eb-8917-080027315160": {
"team": "J2",
"team_location": "Seattle, Washington",
"team_season_id": "d6333181-5040-11eb-8917-080027315160",
"event_team_placement_id": 5412
}
}
}
},
"2018": {
"year": 2018,
"event_id": "537edbe9-5039-11eb-8917-080027315160",
"event_season_id": "e02569e6-5040-11eb-8917-080027315160",
"event_name": "USA Ultimate Masters Championships",
"event_location": "Aurora, Illinois",
"placements": {
"1": {
"e0227383-5040-11eb-8917-080027315160": {
"team": "Furari",
"team_location": "San Diego, California",
"team_season_id": "e0227383-5040-11eb-8917-080027315160",
"event_team_placement_id": 5852
}
},
"2": {
"e029d38a-5040-11eb-8917-080027315160": {
"team": "Boston",
"team_location": "Boston, Massachusetts",
"team_season_id": "e029d38a-5040-11eb-8917-080027315160",
"event_team_placement_id": 5853
}
}
}
}
}
I have an instance of this object called this.tournament. I'm trying to iterate through each year and display the year, as well as the each team in the placements nested object, all in a single row of a table. Right now my html looks like:
<table>
<thead>
<tr>
<th>Year</th>
<th>Champion</th>
<th>2nd Place</th>
<th>Semi-Finalist</th>
<th>Semi-Finalist</th>
</tr>
</thead>
<tbody>
<tr *ngFor='let year_placement of tournament.year_placements | keyvalue'>
<td>{{year_placement.key}}</td>
<td *ngFor='let team_placement of year_placement.value.placements | keyvalue'>
{{team_placement.key}}
</td>
</tr>
</tbody>
</table>
I have 2 problems that I can see. Most importantly, the year is printed out correctly, but I can't figure out how to print the "team" field. team_placement.key prints out the placement like 1, 2, 3...and team_placement.value just says it [Object, object]. I need team_placement.value.team, but that gives me an undefined.
The 2nd problem I want to always generate 5 total <td>s for each row, even if they have to be empty. Right now if there are less than 4 teams in the "placements" object, it will leave the table missing boxes for those last couple columns. How can I make sure that I always generate 5 's?

You can iterate like below :
<table style="border: solid 1px">
<tr *ngFor='let year of tournament?.year_placements | keyvalue' style="border: solid 1px">
<td style="border: solid 1px">{{year.key}}</td>
<ng-container *ngFor='let teams of year.value.placements | keyvalue'>
<td *ngFor="let team of teams.value | keyvalue" style="border: solid 1px">
<ng-container *ngFor="let teamDesc of team.value | keyvalue">
<div *ngIf="teamDesc.key !== 'team_season_id'">
{{teamDesc.value}}</div>
</ng-container>
</td>
</ng-container>
</tr>
</table>

check this
<table border="$1">
<span *ngFor='let year of data | keyvalue'>
<span *ngIf="year.key == 'year_placements'">
<tr *ngFor='let teams of year.value | keyvalue'>
<td>{{teams.value.year | json}}</td>
<span *ngFor='let item of teams.value.placements | keyvalue'>
<span *ngFor='let subItem of item.value | keyvalue'>
<td>{{subItem.value.team}}</td>
</span>
</span>
</tr>
</span>
</span>
</table>
this is the inherited data that's why
here is example

Related

Iterate over object and display it in table Angular (array in array)

I have an api that returns this json.
Student = [
{"name": "Maha",
"age": "18",
"sibling": []
},
{"name": "Jensen",
"age": "19",
"sibling": [{"age": "22", "name": "JensenBrotherName"}]
},
{"name": "Matteo ",
"age": "19",
"sibling": [{"age": "27", "name": "MatteoBrotherName"}]
},
{"name": "Sumayya",
"age": "18",
"sibling": [{"age": "22", "name": "SumayyaBrotherName"}, {"age": "24", "name": "SumayyaBrotherName2"}]
},
{"name": "Caris",
"age": "18",
"sibling": [{"age": "22", "name": "CarisBrotherName"}, {"age": "24", "name": "CarisBrotherName2"}]
}
]
I am trying to display this data in a grid like this image
For the sibling column, I am trying to only display the names without age.
Things that I tried -
Student.sibling showed [object] [object]
And,
nested ngFor like
<div *ngFor ="let item of Student">
<div *ngFor ="let name of item.sibling">
{{name.name}}
</div>
</div>
and it displays all the siblings names for every student like
How can I do this in Angular?
The data provided won't produce the output you've specified.
I'm not sure what you mean by an "Angular" way of iterating through the data, but here's one example:
<table>
<caption>
Students
</caption>
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>Sibling</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let student of students">
<td>{{ student.name }}</td>
<td>{{ student.age }}</td>
<td>
<ng-container *ngFor="let sibling of student.sibling; let last = last">
{{ sibling.name }} ({{ sibling.age }})<ng-container *ngIf="!last"
>,
</ng-container>
</ng-container>
</td>
</tr>
</tbody>
</table>
Which produces the output visible in this Stackblitz

How to create Nested Table in Angular?

I am creating a dynamic table with the data array
let data = [{
"criterialimitId": "3",
"criteriaName": "Test",
"criteriaId": "1",
"criteria": "Max Wager",
"type": "DAILY",
"oprLimit": "2.5",
"status": "1",
"action": "SALE_HOLD",
"plrLimitAllowed": "YES",
"createdAt": "2020-09-22 13:30:02.0",
"updatedAt": "2020-09-22 13:30:02.0",
"attributes": [{
"serviceId": "1",
"serviceName": "Draw Game",
"providers": [{
"providerId": "1",
"providerName": "IGT",
"games": [{
"gameId": "1",
"gameName": "LOTTO"
},
{
"gameId": "2",
"gameName": "LOTTO2"
}
]
},
{
"providerId": "2",
"providerName": "ABC",
"games": [{
"gameId": "2",
"gameName": "AB1"
},
{
"gameId": "23",
"gameName": "AB2"
}
]
}
],
"type": "DAILY",
"status": "1",
"createdAt": "2020-09-22 13:30:03.0",
"updatedAt": "2020-09-22 13:30:03.0"
}]
}]
console.log(data)
I want a table like this:
But I am getting the output like this:
Should I use nested table? How to achieve this?
This is my code so far.
.................
....................
..........................
............................
I don't know what more to explain. #stackoverflow is not letting me post my question because "It looks like your post is mostly code; please add some more details." what more details are required? If anybody can assist, it would be helpful.
<table style="table-layout: fixed;" class="table table-bordered">
<thead>
<tr>
<th class="text-center align-middle">Service Name</th>
<th class="text-center align-middle">Provider Name</th>
<th class="text-center align-middle">Game Name</th>
</tr>
</thead>
<tbody>
<ng-container *ngFor="let attribute of data.attributes">
<tr>
<td>{{attribute.serviceName}}</td>
<td>
<tr *ngFor="let provider of attribute.providers">
<td>
{{provider.providerName}}
</td>
</tr>
</td>
<td>
<tr *ngFor="let provider of attribute.providers">
<td *ngFor="let game of provider.games">
{{game.gameName}} <br>
</td>
</tr>
</td>
</tr>
</ng-container>
</tbody>
</table>
I solved it like this :
<table style="table-layout: fixed;" class="table table-bordered">
<thead>
<tr>
<th class="text-center align-middle">{{'criteriaLimit.serviceName' | translate}}</th>
<th class="text-center align-middle">{{'criteriaLimit.providerName' | translate}}</th>
<th class="text-center align-middle">{{'criteriaLimit.gameName' | translate}}</th>
</tr>
</thead>
<tbody>
<ng-container *ngFor="let attribute of data.attributes; let i = index;">
<ng-container *ngFor="let provider of attribute.providers; let j = index">
<ng-container *ngFor="let game of provider.games; let k = index">
<tr>
<td class="text-center align-middle" *ngIf="j==0 && k==0" [attr.rowspan]="calculateSpan(i)">{{attribute.serviceName}}</td>
<td class="text-center align-middle" *ngIf="k==0" [attr.rowspan]="provider.games.length">{{provider.providerName}}</td>
<td class="text-center align-middle" >{{game.gameName}}</td>
</tr>
</ng-container>
</ng-container>
</ng-container>
</tbody>
</table>

iterating through nested collections to create table with Angular ng-repeat

I'm learning Angular and came across some difficulty when creating table from nested collection.
I simplified a bit my data and table for this example. Please help ;)
Here is what I want to achieve (note continent and country can span across multiple columns):
Continent: | Europe | Asia |
Country: | UK | Spain | China |
City: | Edinburgh | London | Barcelona | Beijing |
Population:| 500000 | 9000000 | 15000000 | 22000000 |
Here is data structure:
function playerCtrl($scope) {
$scope.continents = [
{
"continent": "Europe",
"columnSpan": 3,
"countries": [
{
"country": "UK",
"columnSpan": 2,
"cities": [
{
"city": "Edinburgh",
"info": [
{"population": 500000}
]
},
{
"city": "London",
"info": [
{"population": 9000000}
]
}
]
},
{
"country": "Spain",
"columnSpan": 1,
"cities": [
{
"city": "Barcelona",
"info": [
{"population": 15000000}
]
}
]
}
]
},
{
"continent": "Asia",
"columnSpan": 1,
"countries": [
{
"country": "China",
"columnSpan": 1,
"cities": [
{
"city": "Beijing",
"info": [
{"population": 22000000}
]
}
]
}
]
}
];
}
Here is what I have so far for HTML (continents row is easy, struggling with rest):
<div ng-app>
<div class="container-fluid">
<div class="row">
<!-- Player section -->
<div class="col-sm-8" ng-controller="playerCtrl">
<table class="table table-bordered">
<tr>
<th>Continent:</th>
<td ng-repeat="continent in continents" colspan="{{continent.columnSpan}}">{{continent.continent}}</td>
</tr>
<tr>
<th>Country:</th>
<td ng-repeat="country in continents.countries" colspan="{{country.columnSpan}}">{{country.country}}</td>
</tr>
<tr>
<th>City:</th>
<td ng-repeat="city in country.cieties in continents.countries">{{city.city}}</td>
</tr>
<tr>
<th>Population:</th>
<td ng-repeat="city in country.cieties in continents.countries">{{city.info.population}}</td>
</tr>
</table>
</div>
Link to jsfiddle : https://jsfiddle.net/7on62750/
With a little help of a friend I managed to solve this!
solution was to create functions that get me sub-collections.
Feels a bit hacky so feel free to post better solutions.
JS:
function GetCountries(continents) {
var cuntries = [];
for (var i = 0; i < continents.length; i++) {
var a = continents[i];
cuntries = cuntries.concat(a.countries);
}
return cuntries;
}
$scope.GetCountries = function(continents) {
return GetCountries(continents);
}
$scope.GetCities = function(continents) {
var countries = GetCountries(continents);
var cities = [];
for (var i = 0; i < countries.length; i++) {
var a = countries[i];
cities = cities.concat(a.cities);
}
return cities;
}
Html:
<table class="table table-bordered">
<tr>
<th>Continent:</th>
<td ng-repeat="continent in continents" colspan="{{continent.columnSpan}}">{{continent.continent}}</td>
</tr>
<tr>
<th>Country:</th>
<td ng-repeat="country in GetCountries(continents)" colspan="{{country.columnSpan}}">{{country.country}}</td>
</tr>
<tr>
<th>City:</th>
<td ng-repeat="city in GetCities(continents)">{{city.city}}</td>
</tr>
<tr>
<th>Population:</th>
<td ng-repeat="city in GetCities(continents)">{{city.info[0].population}}</td>
</tr>
</table>
jsfiddle: https://jsfiddle.net/2guo5p6d/

Create a table from REST object by setting data in columnar manner

I have a REST service, which returns this object:
[
{
"id": 100,
"value": "2452"
},
{
"id": 100,
"value": "2458"
},
{
"id": 1,
"value": "2457"
},
{
"id": 1,
"value": "2459"
},
{
"id": 4,
"value": "2460"
},
{
"id": 5,
"value": "3458"
}
]
Now, using this GET service, I want the following table to be built in angular and show it in UI.
100 1 4 5
-------------------
2452 2457 2460 3458
2458 2459
i.e. the unique ids should create the header and the list of values associates to each header value will be appended to respective column.
I have tried something with ng-repeat like this:
<table border="1">
<tr>
<th ng-repeat="column in cols">{{column.id}}</th>
</tr>
<tr>
<td ng-repeat="column in cols">
<md-list>
<md-list-item class="md-2-line" ng-repeat="val in column.values">
<md-checkbox ng-model="item.done"></md-checkbox>
<div class="md-list-item-text">
??
</div>
</md-list-item>
</md-list>
</td>
</tr>
But still wondering how to do the same? Please help.
Try use groupBy filter.
var app = angular.module('anApp', ['angular.filter']);
app.controller('aCtrl', function($scope) {
$scope.data = [
{
"id": 100,
"value": "2452"
},
{
"id": 100,
"value": "2458"
},
{
"id": 1,
"value": "2457"
},
{
"id": 1,
"value": "2459"
},
{
"id": 4,
"value": "2460"
},
{
"id": 5,
"value": "3458"
}
];
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-filter/0.4.7/angular-filter.js"></script>
<div ng-app="anApp" ng-controller="aCtrl">
<table border="1">
<tr>
<th ng-repeat="col in data | groupBy: 'id'">{{col[0].id}}</th>
</tr>
<tbody>
<tr>
<td ng-repeat="col in data | groupBy: 'id'">
<table>
<tr ng-repeat="c in col">
<td> {{c.value}}</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
</div>

Creating a table header(th) and body(td) from json in angular app

I have an angular app where i am trying to create a table from a json. My json is as follows:
[
{
"campus_id": "321",
"name": "0"
},
{
"campus_id": "231",
"name": "1"
},
{
"campus_id": "123",
"name": "2"
}
]
Generally we will create a table in the html as follows:
<table class="table table-striped">
<tr>
<th>
Campus id
</th>
<th>
Name
</th>
</tr>
<tr ng-repeat="item in items">
<td >
{{item.campus_id}}
</td>
<td >
{{item.name}}
</td>
</tr>
</table>
How do i create even the headers from the json instead of defining them ourselves?
I would add the column headers within the json result like so
columnDefs: [
{field: 'campus_id', displayName: 'Campus ID'},
{field: 'name', displayName: 'Name'}],
data:
[
{
"campus_id": "57911000",
"name": "0"
},
{
"campus_id": "57911001",
"name": "HIGHLAND PARK HIGH SCHOOL"
},
{
"campus_id": "57911007",
"name": "P A S S Learning Center School"
}
]
otherwise you could use the key, value pairing ng-repeat="(key,value) in items" with a filter to return 1 row and then use {{key}}