how to open unsafe URL's from angular8? - angularjs

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>

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

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.

Get the element using the text in the row in Protractor from nested repeater

I have the table structured below
<table class="table">
<thead>
<tr>
<th class="checkbox-column"></th>
<th class="main-column main-column--checkbox">Name</th>
</tr>
</thead>
<tbody ng-repeat="(a, b) in tests" class="ng-scope" style="">
<tr class="panel__sub-header">
<td>
<input name="item-checkbox" ng-click="toggleSelectAll(a)" type="checkbox">
</td>
<td colspan="4">
<h4 class="ng-binding">ROW2</h4>
</td>
</tr>
<tr ng-repeat="test in testData" ng-class-odd="'odd'" ng-class-even="'even'" class="ng-scope odd" style="">
<td class="checkbox-column"><input name="item-checkbox" ng-click="checkFunction()" type="checkbox"></td>
<td class="main-column">
<a ng-href="#" class="ng-binding" href="#">test.name</a>
</td>
</tr>
<tr ng-repeat="test in testData" ng-class-odd="'odd'" ng-class-even="'even'" class="ng-scope odd" style="">
<td class="checkbox-column"><input name="item-checkbox" ng-click="checkFunction()" type="checkbox"></td>
<td class="main-column">
<a ng-href="#" class="ng-binding" href="#">test.data</a>
</td>
</tr>
</tbody>
<tbody ng-repeat="(a, b) in tests" class="ng-scope" style="">
<tr class="panel__sub-header">
<td>
<input name="item-checkbox" ng-click="toggleSelectAll(a)" type="checkbox">
</td>
<td colspan="4">
<h4 class="ng-binding">ROW1</h4>
</td>
</tr>
<tr ng-repeat="test in testData" ng-class-odd="'odd'" ng-class-even="'even'" class="ng-scope odd" style="">
<td class="checkbox-column"><input name="item-checkbox" ng-click="checkFunction()" type="checkbox"></td>
<td class="main-column">
<a ng-href="#" class="ng-binding" href="#">test.name</a>
</td>
</tr>
<tr ng-repeat="test in testData" ng-class-odd="'odd'" ng-class-even="'even'" class="ng-scope odd" style="">
<td class="checkbox-column"><input name="item-checkbox" ng-click="checkFunction()" type="checkbox"></td>
<td class="main-column">
<a ng-href="#" class="ng-binding" href="#">test.data</a>
</td>
</tr>
</tbody>
</table>
I have got the root table element by using the below answer https://stackoverflow.com/a/41129924/2833311
But failing to get the nested repeater elements.
getSpecificNestedCell: function(tableObject, rowText, nestedTableObj, rowText1, columnCss) {
var ele = element.all(by.repeater(tableObject)).filter(function(rowElement){
return rowElement.element(by.css("td h4")).getText().then(function(text){
return text.indexOf(rowText) !== -1;
});
}).first();
ele = ele.all(by.repeater(nestedTableObj)).filter(function(rowElement1){
return rowElement1.element(by.linkText(rowText1)).getText().then(function(text1){
return text1.indexOf(rowText1) !== -1;
});
}).first().element(by.css('[' + columnCss + ']'));
findObject.waitUntilReady(ele);
return ele; }
Where as,
tableObject ==> (a, b) in tests
rowText ==> ROW2
nestedTableObj ==> test in testData
rowText1 ==> test.data
columnCss ==> ng-click="checkFunction()"
Using the above code I could able to get the element if it has the single row inside the nested repeated, but it was failing to get the element when the nested repeater has the multiple rows
this should give you what you want I believe
function getSpecificNestedCell(tableObject, rowText, nestedTableObj, rowText1, columnCss) {
return element(by.cssContainingText('tbody[ng-repeat="' + tableObject + '"]', rowText))
.element(by.cssContainingText('tr[ng-repeat="' + nestedTableObj + '"]', rowText1))
.element(by.css('[' + columnCss + ']'));
}
Here is the selector I used working

How to get the td element without using row number in protractor

I have the existing method like below,
getSpecificCell: function(tableObject, rowNumber, columnCss) {
var ele = element(by.repeater(tableObject).row(rowNumber)).element(by.css('[' + columnCss + ']'));
return ele;
}
Is that possible to do the same using the row text instead of rowNumber?
Form the below html I need to get the column value without using the row number
HTML sample:
<table class="table">
<thead>
<tr>
<th class="checkbox-column"></th>
<th class="main-column main-column--checkbox">Name</th>
</tr>
</thead>
<tbody ng-repeat="(a, b) in tests" class="ng-scope" style="">
<tr class="panel__sub-header">
<td>
<input name="item-checkbox" ng-click="toggleSelectAll(a)" type="checkbox">
</td>
<td colspan="4">
<h4 class="ng-binding">ROW2</h4>
</td>
</tr>
<tr ng-repeat="test in testData" ng-class-odd="'odd'" ng-class-even="'even'" class="ng-scope odd" style="">
<td class="checkbox-column"><input name="item-checkbox" ng-click="checkFunction()" type="checkbox"></td>
<td class="main-column">
<a ng-href="#" class="ng-binding" href="#">test.name</a>
</td>
</tr>
<tr ng-repeat="test in testData" ng-class-odd="'odd'" ng-class-even="'even'" class="ng-scope odd" style="">
<td class="checkbox-column"><input name="item-checkbox" ng-click="checkFunction()" type="checkbox"></td>
<td class="main-column">
<a ng-href="#" class="ng-binding" href="#">test.data</a>
</td>
</tr>
</tbody>
<tbody ng-repeat="(a, b) in tests" class="ng-scope" style="">
<tr class="panel__sub-header">
<td>
<input name="item-checkbox" ng-click="toggleSelectAll(a)" type="checkbox">
</td>
<td colspan="4">
<h4 class="ng-binding">ROW1</h4>
</td>
</tr>
<tr ng-repeat="test in testData" ng-class-odd="'odd'" ng-class-even="'even'" class="ng-scope odd" style="">
<td class="checkbox-column"><input name="item-checkbox" ng-click="checkFunction()" type="checkbox"></td>
<td class="main-column">
<a ng-href="#" class="ng-binding" href="#">test.name</a>
</td>
</tr>
<tr ng-repeat="test in testData" ng-class-odd="'odd'" ng-class-even="'even'" class="ng-scope odd" style="">
<td class="checkbox-column"><input name="item-checkbox" ng-click="checkFunction()" type="checkbox"></td>
<td class="main-column">
<a ng-href="#" class="ng-binding" href="#">test.data</a>
</td>
</tr>
</tbody>
</table>
You can use filter() method to filter the array of WebElement. have a look at below example,
getSpecificCell: function(tableObject, expectedRowValue, columnCss) {
var ele =element.all(by.repeater(tableObject).filter(function(rowElement){
return rowElement.element(by.css("td h4")).getText().then(function(rowValue){
return rowValue == expectedRowValue;
})
}).first().element(by.‌​css('[' + columnCss + ']'));
return ele;
}

How to convert an existing table(Html) to jQuery datatable in AngularJS

Below is the html I have used to show data in the table, its working fine.
Now I want to convert it to jQuery Datatables.
HTML:-
<table cellpadding="3" class="table table-bordered">
<thead>
<tr class="success">
<th style="cursor: pointer;" ng-click="sort('DOB')"><b>DOB</b> <span class="glyphicon sort-icon" ng-show="sortKey=='DOB'" ng-class="{'glyphicon-chevron-up':reverse,'glyphicon-chevron-down':!reverse}"></span></th>
<th style="cursor: pointer;" ng-click="sort('StateName')"><b>State</b> <span class="glyphicon sort-icon" ng-show="sortKey=='StateName'" ng-class="{'glyphicon-chevron-up':reverse,'glyphicon-chevron-down':!reverse}"></span></th>
<th style="cursor: pointer;" ng-click="sort('FileId')"><b>Image</b> <span class="glyphicon sort-icon" ng-show="sortKey=='FileId'" ng-class="{'glyphicon-chevron-up':reverse,'glyphicon-chevron-down':!reverse}"></span></th>
<th><b>Actions</b></th>
</tr>
</thead>
<tbody>
<tr dir-paginate="employee in employees|orderBy:sortKey:reverse|filter:search|itemsPerPage:5" ng-model="search">
<td>{{employee.DOB | date:'MM/dd/yyyy' }}
<td>{{employee.StateName}}
</td>
<td>
<img ng-src="UploadedFiles/{{employee.FilePath}}" class="img-circle" style="max-width: 50px" alt='Employee Image Missing' />
</td>
</tr>
</tbody>
</table>

Resources