Iterate through Object array - *ngFor - Angular 6 - javascript

Could some one tell me how to iterate below data structure. ii'm trying to load in normal bootstrap table. but failed. so far i tried to for..loop inside an for of loop. but it returns undefined on 'tableData'
i know its silly and duplicate question. but i don't find solution.
{
"parent":{
"tableHeading":{
"Header1":"ASD",
"Header2":"QQQ",
"Header3":"YYY",
"Header4":"OOO",
},
"tableData":[
{
"Sample_1":"2019-08-19T00:00:00",
"Sample_2":"Johney",
"Sample_3":"30",
"Sample_4":"PA,
},
{
"Sample_1":"2019-08-19T00:00:00",
"Sample_2":"Allen P",
"Sample_3":"29",
"Sample_4":"SA",
},
{
"Sample_1":"2019-08-19T00:00:00",
"Sample_2":"Chris",
"Sample_3":"28",
"Sample_4":"MM",
}
]
}
}

Try like this:
<table border="1">
<tr>
<td *ngFor="let head of data.parent.tableHeading |keyvalue">
{{head.value}}
</td>
</tr>
<tr *ngFor="let item of data.parent.tableData">
<td *ngFor="let element of item | keyvalue">
{{element.value}}
</td>
</tr>
</table>
Working Demo

Related

JSON Object in Object refer in HHML

i have a JSON-datafile of typ: trip. In trip is a object: driver (with name, id etc..).
{
"id": "1",
"gpsStart": "N50.418716° , E006.750000°",
"gpsEnd": "N50.318516° , E006.750000°",
"tripBuinsness": true,
"startOdometer": 25698,
"endOdometer": 25700,
"wayPoints": [
"N50.418716° , E006.750000°",
],
"driver": [{
"name": "Theo"
}]
}
How can I refer the driver name in html?
<tbody>
<tr *ngFor="let trip of trips">
<td>{{trip.projectName}}</td>
<td>{{trip.driver}}</td>
</tr>
</tbody>
You do not need ngFor over trip since its an Object, change it over trip.driver which is an array of Objects,
<tbody>
<tr *ngFor="let driver of trip.driver">
<td>{{driver.name}}</td>
</tr>
</tbody>
If you want the only the first driver you can access him through the 0th index:
<tbody>
<tr *ngFor="let trip of trips">
<td>{{trip.projectName}}</td>
<td>{{trip.driver[0].name}}</td>
</tr>
</tbody>
But if you want all of the drivers add another ngFor loop to your template:
<tbody>
<tr *ngFor="let trip of trips">
<td>{{trip.projectName}}</td>
<td>
<span *ngFor="let d of trip.driver">{{d.name}} </span>
</td>
</tr>
</tbody>
'driver' is an array. I think you can access the name by doing trip.driver[0].name or iterating over trip.driver.

How can I retrieve data from an array which is inside another array and display it in the table?

Using Vue.js , I am able to retrieve and display id,description and location, but why in the tasks column I only have [object Object] in all the rows ?!
(tasks is an array inside jobs array)
<template>
<div>
...
<table class="table table-hover">
<thead>
<tr>
<th v-for="column in columns">
...
</th>
</tr>
</thead>
<tbody>
<tr v-for="work in jobs">
<td>{{work["id"]}}</td>
<td>{{work["description"]}}</td>
<td>{{work["location"]}}</td>
<td v-for="tasks in jobs" >{{work["tasks"]}}</td>
</tr>
</tbody>
</table>
<script>
export default{
data : function() {
return{
columns: ['id', 'description', 'location', 'tasks'],
jobs: '',
update: this.getData()
}
},
methods: {
//to get data from the backend API
getData() {
this.$http
.get('http://localhost:3001/api', (data) => {
this.jobs = data["jobs"]
})
}
}
</script>
You are iterating over jobs and not each task inside the job's tasks
You should do something like -
<tr v-for="work in jobs">
<td>{{work["id"]}}</td>
<td>{{work["description"]}}</td>
<td>{{work["location"]}}</td>
<td v-for="task in work.tasks" >{{task["id"]}} -
{{task["description"]}} - {{task["location"]}}</td>
</tr>
Or however you want to display there. But the idea should be to iterate on the tasks array inside each work object
You'll need to explicitly extract the fields that you want to show from tasks. Also, the syntax for the nested v-for would be something like task in work.tasks, so that your task points to each task inside of your tasks array for each work:
<tr v-for="work in jobs">
<td>{{work["id"]}}</td>
<td>{{work["description"]}}</td>
<td>{{work["location"]}}</td>
<td v-for="task in work.tasks">
{{task["id"]}} <br>
{{task["description"]}} <br>
{{task["location"]}}
</td>
</tr>

ng-repeat in angular 2

Need to display a text area for displaying the details, once the details button is clicked.
It gives an output similar to this table structure
<table>
<th>ID</th>
<th>Title</th>
<tr *ngFor = "let row of indexes">
<td *ngFor = "let id of row>{{id}}</td>
<td><button (click)="showDetails()">DETAILS</td>
</tr>
</table>
<tr *ngIf="isClicked"><td>{{id.details}}</td></tr> ---> This needs to be displayed very next to the row where the button is clicked.
In angular 1.x we can achieve this using ng-repeat-start/ng-repeat-end. In angular 2 I have an clue of including </template ngFor let-row [ngForOf]="indexes">But not sure where to include this. Please suggest.
If i understand your problem correctly, you want to insert two table-rows for each of your indexes.
So if you have something like this in your component class:
rows: any[] = [
{ detailsVisible: false },
{ detailsVisible: false },
{ detailsVisible: false },
{ detailsVisible: false },
{ detailsVisible: false }
];
toggleDetails(row: any) {
row.detailsVisible = !row.detailsVisible;
}
You can do it by using ng-container:
<table>
<ng-container *ngFor="let row of rows">
<tr>
<td (click)="toggleDetails(row)">show details</td>
</tr>
<tr *ngIf="row.detailsVisible">
<td>only visible after click on details cell</td>
</tr>
</ng-container>
</table>
Hope this helps.

From DB they are sending HTML, how to render it in the DOM?

I am receiving an object like this
[
{
"BET": 57630343,
"CUSTOMER": 181645,
"SPORT": "MLB",
"XX_FILL OPEN": "<button class=\"btn\" onclick=\"fillOpen(57630343)\">Fill Open</button>",
"XX_VIEW": null,
"XX_CANCEL": "<input type=\"checkbox\" name=\"sports\" value=\"soccer\" onchange=\"fillOpen(57630343)\"/>"
},...]
I am rendering that object in the DOM, but for now, looks like in the picture below
here is the HTML part for the dynamic table
<table>
<thead>
<tr>
<th ng-repeat="column in cols" ng-init="isXX = column.indexOf('XX') === 0">
<span ng-if="isXX">{{column.substring(3).replace('_', ' ')}}</span>
<span ng-if="!isXX">{{column}}</span>
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in rows">
<td ng-repeat="column in cols">
<span>{{row[column]}}</span>
</td>
</tr>
</tbody>
</table>
and here is the Angular part
ReportsFactory.pendingBets(reportParam).then(function(data) {
if (data.length) {
gridInfo = _.forEach(data, function(item) {return item;});
$scope.rows = gridInfo;
$scope.cols = Object.keys($scope.rows[0]);
}
}
The Database guys are sending me that data as you see it in the json I pasted above.
what I need to know, is, what should I do in order to render those elements in the DOM ?
You can use ngBindHtml for that.
<tbody>
<tr ng-repeat="row in rows">
<td ng-repeat="column in cols" ng-bind-html="row[column]">
</td>
</tr>
</tbody>
Since you're getting the HTML from a $http call, you have to use $sce.trustAsHtml to correctly display this HTML on every single one of your row columns that require this:
$scope.rows.forEach(function(row) {
for (var key in row) {
if (key.indexOf('XX') === 0) {
var value = row[key];
if (value) {
row[key] = $sce.trustAsHtml(value);
}
}
}
});
Here's a working plunkr:http://plnkr.co/edit/7iFUhjg6Q0YIwRi47fDm?p=preview
You can do it by using ngSanitize.
Check it here. https://docs.angularjs.org/api/ngSanitize
Then, you can use ng-bind-html directive, which render HTML code to DOM element.
And, Javascript in the element can be applied with trustAsHtml method of $sce service.
I made an example here.
http://plnkr.co/edit/sTEUIWHwGXSAUSQ2rC8y?p=preview

angular 1.2.15 running concurrent loops

I need to do this:
<tbody>
<tr class=“object.sibling[0]”>
<tr class=“object.sibling[1]”>
<tr class=“object.sibling[2]”>
<tr class=“object.sibling[2].child”>
<tr class=“object.sibling[2].child”>
<tr class=“object.sibling[3]”>
<tr class=“object.sibling[4]”>
however I am not sure how to keep track of two loops that are siblings. I can easily do this:
<tbody>
<tr class=“object.sibling[0]”>
<tr class=“object.sibling[1]”>
<tr class=“object.sibling[2]”>
<tr class=“object.sibling[3]”>
<tr class=“object.sibling[4]”>
<tr class=“object.sibling[2].child”>
<tr class=“object.sibling[2].child”>
but then the rows are out of order.
I found a solution that appears to work using ng-repeat-start and ng-repeat-end that visually does exctally what I want but the extra empty rows needed to end the hg-repeat start loops messes up the table when users copy paste.
<tbody>
<tr ng-repeat-start=“x in object.sibling”>
<td class=“x”>
<tr ng-repeat-start=“y in x.child”>
<td class=“Y”>
<tr ng-repeat-end=“”>
<tr ng-repeat-end=“”>
The problem is that the tr’s though they may represent children of siblings must all be on the same level as if that are all sibings. I cannot figure out how to do this with angular 1.2.15. How do I run two loops that keep track of each other that are not nested?
Hm, interesting scenario you've got. This should work:
<tr ng-repeat-start="sibling in siblings"></tr>
<tr ng-repeat-end ng-repeat="child in sibling.children"></tr>
The idea is to repeat two rows for each sibling, but the second row of each sibling is actually repeated for all of the sibling's children. So, in practice, the second row will only show up (and be repeated) if the sibling actually has children.
Here's a full example:
var app = angular.module('app', []);
app.controller('MainCtrl', function($scope) {
$scope.siblings = [
{
children: [
{}, {}, {}
]
},
{},
{
children: [
{}, {}
]
}
];
});
<div ng-app="app">
<table ng-controller="MainCtrl">
<tr ng-repeat-start="sibling in siblings">
<td>Sibling {{$index}}</td>
</tr>
<tr ng-repeat-end ng-repeat="child in sibling.children">
<td>Sibling child {{$index}}</td>
</tr>
</table>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular.min.js"></script>
Notice how there are no extra <tr> elements.

Categories

Resources