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

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.

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" >

how can i display my nested array in another table angular

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

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>

show/hide th/td in angular dependent on button click without changing table width

I have a Show All or Show Me button which toggles vm.todoShowAll with true or false.
This is my controller code:
var vm = this;
vm.init = function() {
vm.todoShowAll = false;
vm.myName = "Torben";
}
vm.showTodo = function () {
vm.todoShowAll = !vm.todoShowAll;
return false;
}
When Its false I want to show only my ToDo tasks where todos.name==vm.myName and hide the name column in the table
When Its true I want to show all ToDo tasks and show the name column in the table
...and of cause without the table changing shape
Unfortunately this is how it looks now:
I dont know how to filter / unfilter, and I dont know how to avoid the table changing width.
Here is my HTML code:
<table border="0" cellspacing="0" cellpadding="0" class="start-todo start-todo-table start-todo-hover" ng-if="vm.todo.length > 0">
<thead>
<tr class="start-header start-bold start-todo-bg">
<th colspan="6" class="start-padding overflow start-left">
ToDo List
<a ng-click="vm.showTodo()" ng-hide="vm.todoShowAll">
<button class="start-todo-btn start-button" style="width:80px; margin-left:5px;">SHOW ALL</button>
</a>
<a ng-click="vm.showTodo()" ng-show="vm.todoShowAll">
<button class="start-todo-btn start-button" style="width:80px; margin-left:5px;">SHOW ME</button>
</a>
<a ui-sref="book()">
<button class="start-todo-btn start-button" style="width:80px;">NEW TODO</button>
</a>
</th>
</tr>
<tr class="start-header start-head start-todo-bg">
<th class="start-left nowrap" style="min-width:66px;">Property</th>
<th class="start-left overflow" style="width:18%">Category</th>
<th class="start-left overflow" style="width:45%">Task</th>
<th class="start-left overflow" style="width:15%">Time</th>
<th class="start-right overflow" style="width:10%">Day</th>
<th class="start-left overflow" style="width:15%" ng-show="vm.todoShowAll">Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="todos in vm.todo | orderBy:'days'" class="start-text">
<td class="start-left start-border nowrap">{{ todos.property }}</td>
<td class="start-left start-border start-smaller overflow">{{ todos.todoCategory }}</td>
<td class="start-left start-border overflow">{{ todos.task }}</td>
<td class="start-left start-border overflow">{{ todos.time }}</td>
<td class="start-right start-border overflow start-bold greennum">
<span ng-class="(todo.days) > 0 ? 'greennum' : 'rednum'"><b>{{todos.days}}</b></span>
</td>
<td class="start-left start-border overflow" ng-show="vm.todoShowAll">{{ todos.name }}</td>
</tr>
</tbody>
</table>
To filter your columns, you can add a filter to the ng-repeat directive. That would look like this:
<tr ng-repeat="todos in vm.todo | filter:vm.nameFilter | orderBy:'days'" class="start-text">
..
</tr>
then in your controller, you can add the filter function like this:
vm.nameFilter = function(item){
return vm.todoShowAll || item.name === vm.myName;
}
To have the tables have the same width, simply add a width: 100% style to your start-todo-table class:
.start-todo-table {
width: 100%;
}

Resources