how can i display my nested array in another table angular - arrays

i want my nested json array 'orderdetials' to be displayed in another table dialog component , how can i do so?
here is a picture on how it should look enter image description here
i want only orderdetials to be displayed in another table when i click the button on each row as displayed in the picture
here is my .json
"OrderList": [
{
"id": "4",
"operationType": "retail",
"date": "2022-11-21T21:00:00.000Z",
"address": "Romnia",
"custname": "Omar",
"nettotal": 234,
"grosstotal": 987,
"totaltax": 0.008,
"totaldiscount": 0.034,
"quantityTotal": 700,
"orderdetials": [
{
"idd": "razor",
"price": 70,
"quantity": 3,
"discount": 0.06,
"tax": 0.03,
"total": 1000
}
i tried *ngfor but it didnt work .
here is my .html:
<table mat-table [dataSource]="dataSource" matSort>
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header> ID. </th>
<td mat-cell *matCellDef="let element"> {{element.id}} </td>
</ng-container>
<ng-container matColumnDef="date">
<th mat-header-cell *matHeaderCellDef mat-sort-header > Date </th>
<td mat-cell *matCellDef="let element"> {{element.date | date}} </td>
</ng-container>
<ng-container matColumnDef="address">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Address </th>
<td mat-cell *matCellDef="let element"> {{element.address}} </td>
</ng-container>
<ng-container matColumnDef="custname">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Cust-Name </th>
<td mat-cell *matCellDef="let element"> {{element.custname}} </td>
</ng-container>
<ng-container matColumnDef="nettotal">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Net-Total </th>
<td mat-cell *matCellDef="let element"> {{element.nettotal | currency}} </td>
</ng-container>
<ng-container matColumnDef="grosstotal">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Gross-Total </th>
<td mat-cell *matCellDef="let element"> {{element.grosstotal | currency}} </td>
</ng-container>
<ng-container matColumnDef="totaltax">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Total-tax </th>
<td mat-cell *matCellDef="let element"> {{element.totaltax | percent}} </td>
</ng-container>
<ng-container matColumnDef="totaldiscount">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Total-Discount </th>
<td mat-cell *matCellDef="let element"> {{element.totaldiscount | percent}} </td>
</ng-container>
<ng-container matColumnDef="operationType" >
<th mat-header-cell *matHeaderCellDef mat-sort-header> Operation-Type </th>
<td mat-cell *matCellDef="let element"> {{element.operationType}} </td>
</ng-container>
<ng-container matColumnDef="quantityTotal" >
<th mat-header-cell *matHeaderCellDef mat-sort-header> Quantity Total </th>
<td mat-cell *matCellDef="let element"> {{element.quantityTotal + ' Items'}} </td>
</ng-container>
<!-- <ng-container matColumnDef="orderdetials">
<th mat-header-cell *matHeaderCellDef mat-sort-header> detials </th>
<td mat-cell *matCellDef="let element" *ngIf=""> </td>
</ng-container> -->
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
<tr class="mat-row" *matNoDataRow>
<td class="mat-cell" colspan="4">No data matching the filter "{{input.value}}"</td>
</tr>
</table>
.ts :
export interface PeriodicElement {
id : number;
date : string;
address : string;
custname : string ;
netTotal : number;
grossTotal : number;
Totaltax : number;
totaldiscount : number;
operationType : string;
quantityTotal : number ;
orderdetials : Detials[] | MatTableDataSource<Detials>;
}
export interface Detials {
idd : number;
price :number;
quantity : number;
discount : number;
tax : number;
total : number;
}
const ELEMENT_DATA: PeriodicElement[] = [];
#Component({
selector: 'app-detials-click',
templateUrl: './detials-click.component.html',
styleUrls: ['./detials-click.component.css']
})
export class DETIALSCLICKComponent implements OnInit {
displayedColumns: string[] =
['id','operationType','date','address','custname',
'nettotal','grosstotal','totaltax'];
// dataSource = new MatTableDataSource(ELEMENT_DATA);
dataSource: MatTableDataSource<any[]> = new MatTableDataSource<any[]>([ELEMENT_DATA]);
#ViewChild(MatSort) sort: MatSort = new MatSort;
#ViewChild(MatPaginator) paginator!: MatPaginator;
constructor(private api : ApiService,
private dialog : MatDialog,
private cd: ChangeDetectorRef) { }
ngAfterViewInit() {
this.dataSource.sort = this.sort;
this.dataSource.paginator = this.paginator;
}
ngOnInit(): void {
this.GetAllOrders();
}
applyFilter(event: Event) {
const filterValue = (event.target as HTMLInputElement).value;
this.dataSource.filter = filterValue.trim().toLowerCase();
}
GetAllOrders(){
this.api.getOrder().subscribe({
next: res => {
// console.log(res);
this.dataSource = new MatTableDataSource(res);
this.dataSource.sort = this.sort;
this.dataSource.paginator = this.paginator;
}, error :(err) => {
alert("Error while fetching the Orders!!")
}
})
}
}

You can pass orderdetials as dialog data. and use as table's datasource.
This might help you to inspire an idea: Stackblitz

Related

Formatting nested object in a subtable for each row of a main table

what I've been trying to do for a couple of days is to create a table inside my main table, filling it with more specific data regarding the row of my main table I'm going to click on.
This is the structure of data that comes directly from an API (I have withheld the data for privacy reasons)
[dataSource result] (https://i.stack.imgur.com/dQyV6.png)
This is what I tried to do: I have 2 interfaces, one that collects the data of all objects with an object inside that collects the data of "dataMatricola" (my subobject)
interface basematricolaData{
ATM: string;
centroservizi:string;
abi:string;
nomecliente:string;
codiceFabbrica:number;
matricola:string;
indirizzo:string;
citta:string;
provincia:string;
isActive:boolean;
dataMatricola:subMatricolaData;
}
interface subMatricolaData{
DT_primaInstallazione: Date;
DT_fineGaranziaHW: Date;
anniGaranzia: number;
DT_instW10: Date;
tipologiaXFS:number;
shockBuster:boolean;
DT_instShockBuster: Date;
DT_fineGaranziaShockBuster: Date;
anniNoleggio: number;
DT_fineNoleggio: Date;
cassaContinua: boolean;
pmo: string;
modello: number;
numeroATM: number;
VI: boolean;
OnPremise: string;
note: string;
ultimaModifica_User: any;
DT_ultimaModica: Date
}
And when the results from the api return to me, I do this:
{
this.matricole.getData().subscribe({
next: res => {
this.isLoadingResults = false
this.dataSource = new MatTableDataSource(res)
this.dataSource.paginator = this.paginator
this.dataSource.filterPredicate = this.createFilter()
},
error : error => {
console.log(error)
this.user.logout();
}})
}
In my component.html, this is what I tried to do :
<div class = "table-container">
<mat-table [dataSource]="dataSource" id="excel-table" class="main-table" multiTemplateDataRows>
<!-- Colonna categoria -->
<ng-container matColumnDef="ATM">
<th mat-header-cell *matHeaderCellDef> Categoria </th>
<td class ="main-table-cell" mat-cell *matCellDef="let element"> {{element.ATM}} </td>
</ng-container>
<!-- Colonna centro servizi -->
<ng-container matColumnDef="centroservizi">
<th mat-header-cell *matHeaderCellDef> Centro servizi </th>
<td class ="main-table-cell" mat-cell *matCellDef="let element"> {{element.centroservizi}} </td>
</ng-container>
<!-- Colonna abi -->
<ng-container matColumnDef="abi">
<th mat-header-cell *matHeaderCellDef> Abi </th>
<td class ="main-table-cell" mat-cell *matCellDef="let element"> {{element.abi}} </td>
</ng-container>
<!-- Colonna nome cliente -->
<ng-container matColumnDef="nomecliente">
<th mat-header-cell *matHeaderCellDef> Nome Cliente </th>
<td class ="main-table-cell" mat-cell *matCellDef="let element"> {{element.nomecliente}} </td>
</ng-container>
<!-- Colonna matricola -->
<ng-container matColumnDef="matricola">
<th mat-header-cell *matHeaderCellDef> Matricola </th>
<td class ="main-table-cell" mat-cell *matCellDef="let element"> {{element.matricola}} </td>
</ng-container>
<!-- Colonna indirizzo -->
<ng-container matColumnDef="indirizzo">
<th mat-header-cell *matHeaderCellDef> Indirizzo </th>
<td class ="main-table-cell" mat-cell *matCellDef="let element"> {{element.indirizzo}} </td>
</ng-container>
<!-- Colonna citta -->
<ng-container matColumnDef="citta">
<th mat-header-cell *matHeaderCellDef> Città </th>
<td class ="main-table-cell" mat-cell *matCellDef="let element"> {{element.citta}} </td>
</ng-container>
<!-- Colonna provincia -->
<ng-container matColumnDef="provincia">
<th mat-header-cell *matHeaderCellDef> Provincia </th>
<td class ="main-table-cell" mat-cell *matCellDef="let element"> {{element.provincia}} </td>
</ng-container>
<!-- Colonna isactive -->
<ng-container matColumnDef="isActive">
<th mat-header-cell *matHeaderCellDef> Attivo </th>
<td class ="main-table-cell" mat-cell *matCellDef="let element"> {{element.isActive}} </td>
</ng-container>
<!-- Expanded Content Column - The detail row is made up of this one column that spans across all columns -->
<ng-container matColumnDef="expandedDetail">
<td class="subtable-container" mat-cell *matCellDef="let element" [attr.colspan]="displayedColumns.length">
<div class="example-element-detail"
[#detailExpand]="element == expandedElement ? 'expanded' : 'collapsed'">
<mat-table [dataSource]="element.dataMatricola" class="sub-table" >
<ng-container matColumnDef="DT_primaInstallazione">
<th mat-header-cell *matHeaderCellDef> Data prima installazione </th>
<td mat-cell *matCellDef="let element"> {{element.DT_primaInstallazione}} </td>
</ng-container>
<ng-container matColumnDef="DT_fineGaranziaHW">
<th mat-header-cell *matHeaderCellDef> Centro servizi </th>
<td mat-cell *matCellDef="let element"> {{element.DT_fineGaranziaHW}} </td>
</ng-container>
<ng-container matColumnDef="anniGaranzia">
<th mat-header-cell *matHeaderCellDef> Abi </th>
<td mat-cell *matCellDef="let element"> {{element.anniGaranzia}} </td>
</ng-container>
<ng-container matColumnDef="DT_instW10">
<th mat-header-cell *matHeaderCellDef> Data installazione windows 10 </th>
<td mat-cell *matCellDef="let element"> {{element.DT_instW10}} </td>
</ng-container>
<ng-container matColumnDef="tipologiaXFS">
<th mat-header-cell *matHeaderCellDef> Matricola </th>
<td mat-cell *matCellDef="let element"> {{element.tipologiaXFS}} </td>
</ng-container>
<ng-container matColumnDef="modello">
<th mat-header-cell *matHeaderCellDef> Indirizzo </th>
<td mat-cell *matCellDef="let element"> {{element.modello}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="subdisplayedColumns"></tr>
<tr mat-row *matRowDef="let element; columns: subdisplayedColumns;"></tr>
</mat-table>
</div>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let element; columns: displayedColumns;"
class="example-element-row"
[class.example-expanded-row]="expandedElement === element"
(click)="expandedElement = expandedElement === element ? null : element">
</tr>
<tr mat-row *matRowDef="let row; columns: ['expandedDetail']" class="example-detail-row"></tr>
<tr *matNoDataRow>
<td class="mat-cell" colspan="4">La ricerca con i caratteri "{{input.value}}" non ha prodotto alcun risultato</td>
</tr>
</mat-table>
<mat-paginator [pageSizeOptions]="[5, 10]" showFirstLastButtons aria-label="Select page of periodic elements"> </mat-paginator>
<div *ngIf="isLoadingResults" style="display: flex; justify-content: center; align-items: center">
<mat-progress-spinner color="primary" mode="indeterminate"></mat-progress-spinner>
</div>
</div>
But when i try to show the table, this is the error that appears to me :
schermataricerca.component.ts:166 ERROR Error: Provided data source did not match an array, Observable, or DataSource
at getTableUnknownDataSourceError (table.mjs:1024:12)
at MatTable._observeRenderChanges (table.mjs:1763:19)
at MatTable.ngAfterContentChecked (table.mjs:1415:18)
at callHook (core.mjs:2498:18)
at callHooks (core.mjs:2457:17)
at executeInitAndCheckHooks (core.mjs:2408:9)
at refreshView (core.mjs:10460:21)
at refreshEmbeddedViews (core.mjs:11434:17)
at refreshView (core.mjs:10443:9)
at refreshComponent (core.mjs:11480:13)
And obviously, in the table it shows nothing.
Can anyone explain to me how can I show data inside my subobject inside my object in a subtable?
data you pass is not an array
you can create pipe to trasform your data
import { Pipe, PipeTransform } from '#angular/core';
#Pipe({
name: 'yourpipe'
})
export class YourPipe implements PipeTransform {
transform(value:any): unknown {
return [value]
}
}
<mat-table [dataSource]="element.dataMatricola | yourpipe" class="sub-table" >

Get Total of NgFor item Angular

I have an leave array with leave counts of different leave types, I have to return the total of every leave types
array = {
"Jan 2021": [
{
"WFH": 17.5
},
{
"CL": 3.5
}
],
"Feb 2021": [
{
"WFH": 19.5
},
{
"CL": 2.5
}
],
"Mar 2021": [
{
"WFH": 13
}
]
}
This is my html file:
<table class="table table-statitics2 table-bordered" aria-label="Leave">
<thead>
<tr>
<th scope="col"></th>
<th scope="col" class="casual">CL</th>
<th scope="col" class="earned">EL</th>
</tr>
</thead>
<tbody *ngIf="leaves">
<tr *ngFor="let item of leaves | keyvalue : keepOriginalOrder">
<td class="date">{{item.key}}</td>
<td>{{getMonthyItem(item.value, "CL")}}</td>
<td>{{getMonthyItem(item.value, "EL")}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<th colspan="2" class="text-center text-danger" scope="row">Total</th>
<th scope="row">Total of CL</th>
<th scope="row">Total of EL</th>
</tr>
</tfoot>
</table>
this is my function to return Leave Count
getMonthyItem(items, object)
{
let result = '';
items.forEach(element => {
if(Object.keys(element) == object)
{
result = element[object];
}
});
return result;
}
How can I return total of every leave types on footer section of table, also is there any simple way to return leave counts directly on html page without the function, that have used.
Expected result is,
CL
WFH
Jan 2021
3.5
17.5
Feb 2021
2.5
19.5
Mar 2021
1
13
Total
7
50
Thanks............................................................................................................................................................................................
<table class="table table-statitics2 table-bordered" aria-label="Leave">
<thead>
<tr>
<th scope="col"></th>
<th scope="col" class="casual">CL</th>
<th scope="col" class="earned">EL</th>
</tr>
</thead>
<tbody *ngIf="leaves">
<tr *ngFor="let item of leaves | keyvalue : keepOriginalOrder">
<td class="date">{{item.key}}</td>
<td>{{getMonthyItem(item.value, "CL")}}</td>
<td>{{getMonthyItem(item.value, "EL")}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<th colspan="2" class="text-center text-danger" scope="row">Total</th>
<th scope="row">Total of CL</th>
<th scope="row">Total of EL</th>
</tr>
<tr>
<td>total('CL')</td>
<td>total('EL')</td>
</tr>
</tfoot>
</table>
and then in your .ts function define a new function. As I see you already keep as field the leaves which contains all the information. So it would be
public total (type: string): number {
let sum = 0;
Object.keys(this.leaves).forEach(key => {
this.leaves[key].forEach(element => {
sum = sum + (element[type] ? element[type] : 0);
});
});
return sum;
}
The way I would go about it is to calculate the total in a function and add an extra row manually with the data in:
HTML:
<table class="table table-statitics2 table-bordered" aria-label="Leave">
<thead>
<tr>
<th scope="col"></th>
<th scope="col" class="casual">CL</th>
<th scope="col" class="earned">EL</th>
</tr>
</thead>
<tbody *ngIf="leaves">
<tr *ngFor="let item of leaves | keyvalue : keepOriginalOrder">
<td class="date">{{item.key}}</td>
<td>{{getMonthyItem(item.value, "CL")}}</td>
<td>{{getMonthyItem(item.value, "EL")}}</td>
</tr>
<tr>
<td class="date">Total</td>
<td>{{total(leaves, "CL")}}</td>
<td>{{total(leaves, "WFH")}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<th colspan="2" class="text-center text-danger" scope="row">Total</th>
<th scope="row">Total of CL</th>
<th scope="row">Total of EL</th>
</tr>
</tfoot>
</table>
Function:
total(items, object)
{
let result = 0;
items.forEach(x => {
if(Object.keys(x) == object)
{
result = result + x[object];
}
});
return result;
}

Angular material table merge col in first row in table

I want to make a table like this, but am not having a way to make the first row in the table possible to do like this. I hope you can show me how to do it, thank.image table
here is my html:
<div class="table-container">
<table mat-table [dataSource]="tableData">
<ng-container matColumnDef="colspan-stt">
<th mat-header-cell *matHeaderCellDef [attr.rowspan]="2" style=" width: 50px ">Stt</th>
</ng-container>
<ng-container matColumnDef="stt">
<th mat-header-cell *matHeaderCellDef [ngStyle]="{'display': 'none'}"
style=" width: 50px ">Stt
</th>
<td mat-cell *matCellDef="let element"> </td>
</ng-container>
<ng-container matColumnDef="colspan-kyHieu">
<th mat-header-cell *matHeaderCellDef [attr.rowspan]="2" style=" width: 70px ">Ký hiệu</th>
</ng-container>
<ng-container matColumnDef="kyHieu">
<th mat-header-cell *matHeaderCellDef [ngStyle]="{'display': 'none'}" style=" width: 70px ">Stt
</th>
<td mat-cell *matCellDef="let element"></td>
</ng-container>
<ng-container matColumnDef="colspan-congDung">
<th mat-header-cell *matHeaderCellDef [attr.rowspan]="2">Công dụng</th>
</ng-container>
<ng-container matColumnDef="congDung">
<th mat-header-cell *matHeaderCellDef [ngStyle]="{'display': 'none'}">Công dụng
</th>
<td mat-cell *matCellDef="let element"></td>
</ng-container>
<ng-container matColumnDef="colspan-ngayBd">
<th mat-header-cell *matHeaderCellDef [attr.rowspan]="2">Ngày BĐ ghi NKGS</th>
</ng-container>
<ng-container matColumnDef="ngayBd">
<th mat-header-cell *matHeaderCellDef [ngStyle]="{'display': 'none'}">Ngày BĐ ghi NKGS
</th>
<td mat-cell *matCellDef="let element"></td>
</ng-container>
<ng-container matColumnDef="colspan-thiCong">
<th mat-header-cell *matHeaderCellDef [attr.colspan]="2" style=" width: 140px ">Thi công
</th>
</ng-container>
<ng-container matColumnDef="thiCongMong">
<th mat-header-cell *matHeaderCellDef style=" width: 70px ">Móng
</th>
<td mat-cell *matCellDef="let element"></td>
</ng-container>
<ng-container matColumnDef="thiCongCot">
<th mat-header-cell *matHeaderCellDef style=" width: 70px ">Cột
</th>
<td mat-cell *matCellDef="let element"></td>
</ng-container>
<ng-container matColumnDef="colspan-nghiemThu">
<th mat-header-cell *matHeaderCellDef [attr.colspan]="6" style=" width: 420px ">Nghiệm
thu</th>
</ng-container>
<ng-container matColumnDef="nghiemThuDaoMong">
<th mat-header-cell *matHeaderCellDef style=" width: 70px ">Đào móng
</th>
<td mat-cell *matCellDef="let element"></td>
</ng-container>
<ng-container matColumnDef="nghiemThuCotThep">
<th mat-header-cell *matHeaderCellDef style=" width: 70px ">Cốt thép
</th>
<td mat-cell *matCellDef="let element"></td>
</ng-container>
<ng-container matColumnDef="nghiemThuDucMong">
<th mat-header-cell *matHeaderCellDef style=" width: 70px ">Đúc móng
</th>
<td mat-cell *matCellDef="let element"></td>
</ng-container>
<ng-container matColumnDef="nghiemThuLapMong">
<th mat-header-cell *matHeaderCellDef style=" width: 70px ">Lấp móng
</th>
<td mat-cell *matCellDef="let element"></td>
</ng-container>
<ng-container matColumnDef="nghiemThuDungCot">
<th mat-header-cell *matHeaderCellDef style=" width: 70px ">Dựng cột
</th>
<td mat-cell *matCellDef="let element"></td>
</ng-container>
<ng-container matColumnDef="nghiemThuChuyenGd">
<th mat-header-cell *matHeaderCellDef style=" width: 70px ">Chuyển GĐ
</th>
<td mat-cell *matCellDef="let element"></td>
</ng-container>
<ng-container matColumnDef="colspan-hoanCong">
<th mat-header-cell *matHeaderCellDef [attr.colspan]="2" style=" width: 140px ">Hoàn công
</th>
</ng-container>
<ng-container matColumnDef="hoanCongMong">
<th mat-header-cell *matHeaderCellDef style=" width: 70px ">Móng
</th>
<td mat-cell *matCellDef="let element"></td>
</ng-container>
<ng-container matColumnDef="hoanCongCot">
<th mat-header-cell *matHeaderCellDef style=" width: 70px ">Cột
</th>
<td mat-cell *matCellDef="let element"></td>
</ng-container>
<ng-container matColumnDef="colspan-nhatKy">
<th mat-header-cell *matHeaderCellDef [attr.rowspan]="2">Nhật ký (Chưa có/Phải có)</th>
</ng-container>
<ng-container matColumnDef="nhatKy">
<th mat-header-cell *matHeaderCellDef [ngStyle]="{'display': 'none'}">Nhật ký (Chưa có/Phải có)
</th>
<td mat-cell *matCellDef="let element"></td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumnsLv2; sticky: true"></tr>
<tr mat-header-row *matHeaderRowDef="displayedColumnsLv1;sticky: true"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumnsLv1;"></tr>
</table>
</div>
And ts
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-table-mongcot',
templateUrl: './table-mongcot.component.html',
styleUrls: ['./table-mongcot.component.scss']
})
export class TableMongcotComponent implements OnInit {
displayedColumnsLv1 = ["stt", "kyHieu", "congDung", "ngayBd", "thiCongMong", "thiCongCot", "nghiemThuDaoMong", "nghiemThuCotThep", "nghiemThuDucMong", "nghiemThuLapMong", "nghiemThuDungCot", "nghiemThuChuyenGd", "hoanCongMong", "hoanCongCot", "nhatKy"]
displayedColumnsLv2 = ["colspan-stt", "colspan-kyHieu", "colspan-congDung", "colspan-ngayBd", "colspan-thiCong", "colspan-nghiemThu", "colspan-hoanCong", "colspan-nhatKy"]
tableData: any = ['', '', '']
constructor() { }
ngOnInit(): void {
}
}

how to open unsafe URL's from angular8?

I am trying to open a hyperlink change://problem/12345678 as below from angular8 UI but it always gets redirected go unsafe:change://problem/12345678 and doesnt open the link,I looked at AngularJS changes URLs to "unsafe:" in extension page and tried to use ng-href and running into below error,is there a simpler way to do this in angular8?
<table mat-table [dataSource]="newPost.posts" multiTemplateDataRows
class="table table-bordered table-info" style="text-align:center" *ngIf="enteredValue != ''">
<ng-container matColumnDef="{{column}}" *ngFor="let column of columnsToDisplay; let idx=index">
<th style="color: black;" mat-header-cell *matHeaderCellDef> {{column}} </th>
<span *ngIf="idx == 0">
<td style="color: black;" mat-cell *matCellDef="let element">
{{element[column]}} </td>
</span>
<span *ngIf="idx == 5">
<table mat-cell *matCellDef="let element">
<tr *ngFor="let gerrit of element[column]">
{{gerrit}}
</tr>
</table>
</span>
<span *ngIf="idx != 0 && idx != 5">
<td style="color: black;" mat-cell *matCellDef="let element"> {{element[column]}} </td>
</span>
</ng-container>
Error:-
Uncaught Error: Template parse errors:
Can't bind to 'ng-href' since it isn't a known property of 'a'. (" <span *ngIf="idx2 == 0">
<td mat-cell *matCellDef="let big_beast"> <a
[ERROR ->]ng-href="change://problem/{{big_beast[tempy]}}">{{big_beast[tempy]}} </a>
</td>
"): ng:///AppModule/RadarInputComponent.html#109:15
at syntaxError (compiler.js:2175)
at TemplateParser.parse (compiler.js:11169)
at JitCompiler._parseTemplate (compiler.js:25541)
at JitCompiler._compileTemplate (compiler.js:25529)
at compiler.js:25473
at Set.forEach (<anonymous>)
at JitCompiler._compileComponents (compiler.js:25473)
at compiler.js:25386
at Object.then (compiler.js:2166)
at JitCompiler._compileModuleAndComponents (compiler.js:25385)
You have to use DomSanitizer#bypassSecurityTrustUrl:
class FooComponent {
public constructor(private sanitizer: DomSanitizer) {}
public getUrl(column: string) {
return this.sanitizer.bypassSecurityTrustUrl(`change://problem/${column}`)
}
}
and in the template:
<a [attr.href]="getUrl(element[column])">{{ element[column] }}</a>

I have a JSON array with 4 elements in angular 7, but it shows 0 when I asked for it`s length

I have an API that responds a JSON object to request. Everything looks normal but when I want to access to elements of this JSON Array it shows 0 elements instead of true value.
it's my request :
private request(type: 'getall'|'getonebyid'|'addnew'|'editbyid'|'deleteonebyid',
mp?: IMeasurementInterfaces,
id?: string): Observable<any> {
let base;
this.serverUri = 'http://localhost:3000'; // localhost
if (type === 'getall') {
base = this.http.get<MeasurementDetails[]>(`${this.serverUri}/mea/${type}`);
}
const request = base.pipe(
map((data: any) => {
return data;
})
);
return request;
}
call request function :
public getall(): Observable<MeasurementDetails[]> {
return this.request('getall');
}
filling mpserv declared in component.ts file:
this.mpserv.getall().subscribe(
x => {
x.forEach(element => {
this.mp.push(element);
});
},
err => console.error('Observer got an error: ' + err),
() => console.log('Observer got a complete notification')
);
when I request console.log(this.mpserv) it responds this:
I used this.mp as data source of data table :
<div class="measurement-type-grid">
<div class="measurement-type-list">
<table mat-table [dataSource]="dataSource">
<!-- Position Column -->
<ng-container matColumnDef="position">
<th mat-header-cell *matHeaderCellDef> No. </th>
<td mat-cell *matCellDef="let element"> {{element.position}} </td>
</ng-container>
<!-- title Column -->
<ng-container matColumnDef="title">
<th mat-header-cell *matHeaderCellDef> title </th>
<td mat-cell *matCellDef="let element"> {{element.title}} </td>
</ng-container>
<!-- description Column -->
<ng-container matColumnDef="description">
<th mat-header-cell *matHeaderCellDef> description </th>
<td mat-cell *matCellDef="let element"> {{element.description}} </td>
</ng-container>
<!-- Symbol Column -->
<ng-container matColumnDef="symbol">
<th mat-header-cell *matHeaderCellDef> Symbol </th>
<td mat-cell *matCellDef="let element"> {{element.symbol}} </td>
</ng-container>
<!-- Edit Column -->
<ng-container matColumnDef="edit">
<th mat-header-cell *matHeaderCellDef> Edit </th>
<td mat-cell *matCellDef="let element">
<button mat-icon-button color="primary">
<mat-icon aria-label="Edit data">edit</mat-icon>
</button>
</td>
</ng-container>
<!-- Delete Column -->
<ng-container matColumnDef="delete">
<th mat-header-cell *matHeaderCellDef> Delete </th>
<td mat-cell *matCellDef="let element">
<button mat-icon-button color="primary">
<mat-icon aria-label="Delete data">delete_forever</mat-icon>
</button>
</td>
</ng-container>
<!-- Add New Column -->
<ng-container matColumnDef="add new">
<th mat-header-cell *matHeaderCellDef> Add New </th>
<td mat-cell *matCellDef="let element">
<button mat-icon-button color="primary">
<mat-icon aria-label="Delete data">add_circle</mat-icon>
</button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<mat-paginator [pageSizeOptions]="[5, 10, 20]" showFirstLastButtons></mat-paginator>
</div>
</div>
I used this function to fill data to data source:
filltoelements(mdata: MeasurementDetails[]) {
// console.log(mdata);
if (!mdata) {
console.log('data is undefined!!!!');
} else {
let i: number;
i = -1;
mdata.forEach(element => {
i++;
this.ELEMENT_DATA[i].position = i + 1;
this.ELEMENT_DATA[i].title = element.measureTitle;
this.ELEMENT_DATA[i].description = element.measureDescription;
this.ELEMENT_DATA[i].symbol = element.measureSymbol;
this.ELEMENT_DATA[i].edit = 'edit';
this.ELEMENT_DATA[i].delete = 'delete';
this.ELEMENT_DATA[i].addNew = 'addNew';
});
}
}
and I defined it in component.ts:
displayedColumns: string[] = ['position', 'title', 'description', 'symbol', 'edit', 'delete', 'add new'];
dataSource = new MatTableDataSource<MeasureTypeElemetns>(this.ELEMENT_DATA);
and returned 0 as array length and my data table is empty:
do you have any idea?
Thanks to pjlamb12, Gilsdav and AjayReddy.
I should do it within subscribe method. so my code should be something like this :
this.mpserv.getall().subscribe(
x => {
x.forEach(element => {
this.mp.push(element);
});
this.filltoelements(this.mp);
},
err => console.error('Observer got an error: ' + err),
() => console.log('Observer got a complete notification')
);
then it worked properly.

Resources