ng-select with FormArray in Angular Reactive Form - angular-ngselect

Ng-Select#
when i use ng-select within FormArray although i get specialities from backend but it is
not working
<ng-container [formGroup]="form">
<ng-container *ngIf="academicDgrees">
<ng-container formArrayName="ProfileAcademicDegree" *ngFor="let degree of
academicDgrees?.value; let indx=index; let last=last">
<ng-container [formGroupName]="indx">
<ng-select
formControlName="SpecialtyId"
[items]="specialities"
bindLabel="Name"
placeholder="اختر التخصص"
bindValue="Id"
notFoundText="لا يوجد تخصصات" >
</ng-select>
</ng-container>
</ng-container>
</ng-container>
</ng-container>

Related

mat-table-filter with REST API call

I am using Angular 14.2.7. My requirement here is need to make REST call and populate data in UI. Once data is available need to filter out based on column. I can defined filter column in ngOnInit method. I can populate data. When i use filter without it is giving me correct result.
I mean it filter out the records from all columns.
When i use filterPredicate (to search in specific column) is not able to search the record. In browser console i can see below error
main.ts:11 ERROR TypeError: Cannot set properties of undefined (setting 'filterPredicate')
at AppComponent.ngOnInit (app.component.ts:30:36)
at callHook (core.mjs:2498:22)
at callHooks (core.mjs:2467:17)
at executeInitAndCheckHooks (core.mjs:2418:9)
at refreshView (core.mjs:12026:21)
at detectChangesInternal (core.mjs:13229:9)
at RootViewRef.detectChanges (core.mjs:13741:9)
at ApplicationRef.tick (core.mjs:27377:22)
at ApplicationRef._loadComponent (core.mjs:27415:14)
at ApplicationRef.bootstrap (core.mjs:27352:14)
After reading this error i can understand some my REST call is still running and tried to this.dataSource.filterPredicate.
What changes i need to do achive this.?
Please find my code.
import { HttpClient } from '#angular/common/http';
import { MatTableDataSource, MatTableModule } from '#angular/material/table';
import { DataSource } from '#angular/cdk/table';
import { Component } from '#angular/core';
import {MatInputModule} from '#angular/material/input';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'Sample-App';
li: any;
lis = [];
dataSource: any;
displayedColumns: string[] = ['name', 'position', 'office', 'salary'];
public data = {list: [{name:'Billy Lee',position:'Web Developer',office:'Detroit',salary:'$50000'},{name:'John Doe',position:'Manager',office:'Troy',salary:'$90000'},{name:'James Baxter',position:'IT Support',office:'Detroit',salary:'$30000'}]};
constructor(private http: HttpClient) { }
ngOnInit() {
this.getData().subscribe((data: any) => {
this.dataSource = new MatTableDataSource(data.list);
console.log("API", data);
});
this.dataSource.filterPredicate = function (dataSource : any, filter : string) {
return dataSource.name.toLocaleLowerCase() == filter.toLocaleLowerCase();
}
}
getData() {
return this.http.get('http://www.mocky.io/v2/5ea172973100002d001eeada');
}
applyFilter(event: Event) {
const filterValue = (event.target as HTMLInputElement).value;
this.dataSource.filter = filterValue.trim().toLowerCase();
}
}
HTML
<mat-form-field appearance="standard">
<mat-label>Filter</mat-label>
<input (keyup)="applyFilter($event)" matInput placeholder="Search columns" #input>
</mat-form-field>
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
<!--- Note that these columns can be defined in any order.
The actual rendered columns are set as a property on the row definition" -->
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
<!-- name Column -->
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef> Name </th>
<td mat-cell *matCellDef="let Employees"> {{Employees.name}} </td>
</ng-container>
<!-- position Column -->
<ng-container matColumnDef="position">
<th mat-header-cell *matHeaderCellDef> Position </th>
<td mat-cell *matCellDef="let Employees"> {{Employees.position}} </td>
</ng-container>
<!-- office Column -->
<ng-container matColumnDef="office">
<th mat-header-cell *matHeaderCellDef> office </th>
<td mat-cell *matCellDef="let Employees"> {{Employees.office}} </td>
</ng-container>
<!-- salary Column -->
<ng-container matColumnDef="salary">
<th mat-header-cell *matHeaderCellDef> salary </th>
<td mat-cell *matCellDef="let Employees"> {{Employees.salary}} </td>
</ng-container>
</table>

Datasource data is not populating

I am new babie in Angular (Currently using 14.2.10)
Need to make REST call and populate the data in UI. But I can see only header is populated without any data.
I feel some minor issue (Not able to figure out). In Developer console i can see data is populating. But not in UI.
Please find my html and TS file.
app.component.html
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
<!--- Note that these columns can be defined in any order.
The actual rendered columns are set as a property on the row definition" -->
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
<!-- name Column -->
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef> Name </th>
<td mat-cell *matCellDef="let Employees"> {{Employees.name}} </td>
</ng-container>
<!-- position Column -->
<ng-container matColumnDef="position">
<th mat-header-cell *matHeaderCellDef> Position </th>
<td mat-cell *matCellDef="let Employees"> {{Employees.position}} </td>
</ng-container>
<!-- office Column -->
<ng-container matColumnDef="office">
<th mat-header-cell *matHeaderCellDef> office </th>
<td mat-cell *matCellDef="let Employees"> {{Employees.office}} </td>
</ng-container>
<!-- salary Column -->
<ng-container matColumnDef="salary">
<th mat-header-cell *matHeaderCellDef> salary </th>
<td mat-cell *matCellDef="let Employees"> {{Employees.salary}} </td>
</ng-container>
</table>
app.component.ts
import { Component } from '#angular/core';
import {HttpClient} from '#angular/common/http';
import { MatTableDataSource, MatTableModule } from '#angular/material/table';
import { DataSource } from '#angular/cdk/table';
export interface Employees {
name: string;
position: string;
office:string ;
salary: number;
}
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'Sample-App';
li:any;
lis=[];
datasource: any;
displayedColumns: string[] = ['name', 'position', 'office', 'salary'];
constructor(private http : HttpClient){
}
ngOnInit() {
this.http.get('http://www.mocky.io/v2/5ea172973100002d001eeada')
.subscribe(Response => {
console.log(Response)
this.li=Response;
this.lis=this.li.list;
this.datasource = new MatTableDataSource(this.lis);
console.log(this.datasource)
});
}
}
Output :
In Developer mode i can see
Please correct me where i am going wrong.
Your code is fine. See here: Stackblitz
It looks like you need to fix your dependencies. You're using Angular 14.2.10, but Material 13.0 and Material CDK 13.3.9.
EDIT
I updated the Stackblitz, before I was getting the error:
Mixed Content: The page at '<URL>' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint '<URL>'. This request has been blocked; the content must be served over HTTPS.
The URL you provided wasn't secure, so I changed from:
http://www.mocky.io/v2/5ea172973100002d001eeada
to
https://www.mocky.io/v2/5ea172973100002d001eeada
The Stackblitz works fine with the rest of the code you provided.

How to do I pass unique identifier from button to Modal in Handlebars?

I'm creating a Accounting Web System using Nodejs and Express with Handlebars (.hbs), while using Bootstrap as my main Frontend toolkit. I have a dynamic table with each row consisting of information and three buttons. With delete button ("eliminar"), I'm adding a modal to verify that the user actually wants to delete information instead of by accident.
However, when inserting the modal into my handlebar, the information no longer belongs to its appropriate row but rather the first row from the query object rendered into the handlebar. My code looks like this:
<table class="table table-bordered">
<thead class="thead-dark text-center">
<tr>
<th scope="col">Tipo ID</th>
<th scope="col">Tipo Codigo</th>
<th scope="col">Tipo Descripcion</th>
<th scope="col">Acciones</th>
<th scope="col">Usuario</th>
{{!-- <th scope="col">Tiempo Creado:</th> --}}
</tr>
</thead>
<tbody class="text-center">
{{#each tipoparametro}}
<tr>
<th scope="row">{{this.tipoparid}}</th>
<td>{{this.tipoparcodigo}}</td>
<td>{{this.tipodescripcion}}</td>
<td class="text-center">
<a href="/viewuser/{{this.tipoparid}}" type="button" class="btn btn-outline-info btn-small"><i
class="bi bi-eye"></i>Ver</a>
<a href="/edituser/{{this.tipoparid}}" type="button" class="btn btn-outline-primary btn-small"><i
class="bi bi-pencil"></i>Modificar</a>
<a href="/delete/{{this.tipoparid}}" type="button" class="btn btn-outline-danger btn-small"
value={{this.tipoparid}} data-bs-toggle="modal" data-bs-target="#staticBackdrop"
data-target={{this.tipoparid}}><i class="bi bi-person-x"></i>Eliminar - {{this.tipoparid}}</a>
</td>
{{!-- New --}}
<!-- Modal -->
<div class="modal fade" id="staticBackdrop" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1"
aria-labelledby="staticBackdropLabel" aria-hidden="true" value={{this.tipoparid}}>
<div class="modal-dialog text-center">
<div class="modal-content">
<div class="modal-header text-center">
<h5 class="modal-title w-100" id="staticBackdropLabel">Eliminar
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body ">
Estas seguro que quieres eliminar este Tipo Parametro:
<hr>
<p class="card-text"><strong>Id:</strong> {{this.tipoparid}}</p>
<p class="card-text"><strong>Codigo de Parametro:</strong> {{this.tipoparcodigo}}</p>
<p class="card-text"><strong>Usuario:</strong> {{this.usuarionombre}}</p>
<p class="card-text"><strong>Descripcion:</strong> {{this.tipodescripcion}}</p>
</div>
<div class="modal-footer d-flex justify-content-between">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cerrar</button>
<a type="button" class="btn btn-outline-danger yes" href="/delete/{{this.tipoparid}}">Eliminar</a>
</div>
</div>
</div>
</div>
{{!-- New --}}
<td>{{this.usuarionombre}}</td>
</tr>
{{/each}}
</tbody>
</table>
Is there a simplified way to pass the unique identifier this.tipoparid into the modal so I can obtain the correct info from each row and not from the first all the time?
It's important for me to output the information inside the modal according to its row.

Angular Material Table Sorting Not Working Code In Post

Im not sure what my issue is here i see the arrow and i can log the sorting to the console and see that its seeing the field it should be sorting but when i click the table arrow to sort by username it doesnt sort it my code will be below any help pointing out what I may be doing wrong would be a huge help thanks everyone.
player-list.component.html
<mat-form-field>
<input
matInput
(keyup)="applyFilter($event.target.value)"
placeholder="Filter"
/>
</mat-form-field>
<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">
<!-- Position Column -->
<ng-container matColumnDef="Username">
<th mat-header-cell *matHeaderCellDef mat-sort-header>username</th>
<td mat-cell *matCellDef="let user">{{ user.UserName }}</td>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="Region">
<th mat-header-cell *matHeaderCellDef>Region</th>
<td mat-cell *matCellDef="let user">{{ user.Region }}</td>
</ng-container>
<ng-container matColumnDef="Earnings">
<th mat-header-cell *matHeaderCellDef>Earnings</th>
<td mat-cell *matCellDef="let user">{{ user.Earnings }}</td>
</ng-container>
<!-- Weight Column -->
<ng-container matColumnDef="Wins">
<th mat-header-cell *matHeaderCellDef>Wins</th>
<td mat-cell *matCellDef="let user">{{ user.Wins }}</td>
</ng-container>
<!-- Symbol Column -->
<ng-container matColumnDef="Loses">
<th mat-header-cell *matHeaderCellDef>Loses</th>
<td mat-cell *matCellDef="let user">{{ user.Loses }}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
</table>
player-list.component.ts
import { UserService } from "./../../../services/API/userAPI";
import { User } from "./../../../services/API/user.model";
import { Component, OnInit, ViewChild } from "#angular/core";
import { MatPaginator, MatSort, Sort } from "#angular/material";
import { MatTableDataSource } from "#angular/material/table";
#Component({
selector: "app-player-list",
styleUrls: ["player-list.component.css"],
templateUrl: "player-list.component.html"
})
export class PlayerListComponent implements OnInit {
public userArray: User[];
dataSource: MatTableDataSource<any>;
displayedColumns: string[] = [
"Username",
"Region",
"Earnings",
"Wins",
"Loses"
];
constructor(public userService: UserService) {}
#ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
#ViewChild(MatSort, { static: true }) sort: MatSort;
applyFilter(filterValue: string) {
this.dataSource.filter = filterValue.trim().toLowerCase();
}
ngOnInit() {
this.userService.getAllUsers().subscribe(res => {
this.dataSource = new MatTableDataSource(res);
this.dataSource.sort = this.sort;
this.dataSource.paginator = this.paginator;
console.log(this.dataSource.sort);
});
}
}
Fix my issues if you look at this code here
<ng-container matColumnDef="Username">
<th mat-header-cell *matHeaderCellDef mat-sort-header="UserName">Username</th>
<td mat-cell *matCellDef="let user">{{ user.UserName }}</td>
</ng-container>
you will see mat-sort-header="UserName" i had that set to Username before not realizing that it needed to match the user.UserName

How to export Excel file from Angular Material 5 Mat-Table (Angular Material Table)?

I am new to Angular and using Angular material 5 mat-table and trying to export the table in a excel file. I have use SheetJS XLSX package.
Below is my code:
Table.component.html:
<mat-table #table [dataSource]="dataSource" matSort>
<!-- ID Column -->
<!--<ng-container matColumnDef="ID">
<mat-header-cell *matHeaderCellDef mat-sort-header> UserID </mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.UserID}} </mat-cell>
</ng-container>-->
<!-- Progress Column -->
<ng-container matColumnDef="MSID">
<mat-header-cell *matHeaderCellDef mat-sort-header> MSID </mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.MSID}} </mat-cell>
</ng-container>
<ng-container matColumnDef="MSPW">
<mat-header-cell *matHeaderCellDef mat-sort-header> MS Password </mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.MSPW}} </mat-cell>
</ng-container>
<ng-container matColumnDef="MSRequsest">
<mat-header-cell *matHeaderCellDef mat-sort-header> MS Requsest </mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.MSRequsest}} </mat-cell>
</ng-container>
<ng-container matColumnDef="ClassID">
<mat-header-cell *matHeaderCellDef mat-sort-header> Class ID </mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.ClassID}} </mat-cell>
</ng-container>
<ng-container matColumnDef="ClassName">
<mat-header-cell *matHeaderCellDef mat-sort-header> Class Name </mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.ClassName}} </mat-cell>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="FirstName">
<mat-header-cell *matHeaderCellDef mat-sort-header> First Name </mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.FirstName}} </mat-cell>
</ng-container>
<ng-container matColumnDef="LastName">
<mat-header-cell *matHeaderCellDef mat-sort-header> Last Name </mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.LastName}} </mat-cell>
</ng-container>
<ng-container matColumnDef="Email">
<mat-header-cell *matHeaderCellDef mat-sort-header> Email </mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.Email}} </mat-cell>
</ng-container>
<ng-container matColumnDef="Role">
<mat-header-cell *matHeaderCellDef mat-sort-header> Role </mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.EmployeeRole}} </mat-cell>
</ng-container>
<ng-container matColumnDef="EmployeeRoleFrom">
<mat-header-cell *matHeaderCellDef mat-sort-header> Employee Role From </mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.EmployeeRoleFrom}} </mat-cell>
</ng-container>
<ng-container matColumnDef="VendorID">
<mat-header-cell *matHeaderCellDef mat-sort-header> Vendor ID </mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.VendorID}} </mat-cell>
</ng-container>
<ng-container matColumnDef="VendorNameCompany">
<mat-header-cell *matHeaderCellDef mat-sort-header> Vendor Name Company </mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.VendorNameCompany}} </mat-cell>
</ng-container>
<ng-container matColumnDef="StaffID">
<mat-header-cell *matHeaderCellDef mat-sort-header> Staff ID </mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.StaffID}} </mat-cell>
</ng-container>
<ng-container matColumnDef="Source">
<mat-header-cell *matHeaderCellDef mat-sort-header> Source </mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.Source}} </mat-cell>
</ng-container>
<ng-container matColumnDef="HireDate">
<mat-header-cell *matHeaderCellDef mat-sort-header> Hire Date </mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.HireDate}} </mat-cell>
</ng-container>
<ng-container matColumnDef="HireType">
<mat-header-cell *matHeaderCellDef mat-sort-header> Hire Type </mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.HireType}} </mat-cell>
</ng-container>
<ng-container matColumnDef="EnteredDate">
<mat-header-cell *matHeaderCellDef mat-sort-header> Entered Date </mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.EnteredDate}} </mat-cell>
</ng-container>
<ng-container matColumnDef="FloorDate">
<mat-header-cell *matHeaderCellDef mat-sort-header> Floor Date </mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.FloorDate}} </mat-cell>
</ng-container>
<ng-container matColumnDef="SiteLocation">
<mat-header-cell *matHeaderCellDef mat-sort-header> Site Location </mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.SiteLocation}} </mat-cell>
</ng-container>
<ng-container matColumnDef="EmployeeContractorID">
<mat-header-cell *matHeaderCellDef mat-sort-header> Employee Contractor ID </mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.EmployeeContractorID}} </mat-cell>
</ng-container>
<ng-container matColumnDef="TransferFrom">
<mat-header-cell *matHeaderCellDef mat-sort-header> Transfer From </mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.TransferFrom}} </mat-cell>
</ng-container>
<ng-container matColumnDef="Notes">
<mat-header-cell *matHeaderCellDef mat-sort-header> Notes </mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.Notes}} </mat-cell>
</ng-container>
<ng-container matColumnDef="Status">
<mat-header-cell *matHeaderCellDef mat-sort-header> Status </mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.Status}} </mat-cell>
</ng-container>
<!-- Action Column -->
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;">
</mat-row>
</mat-table>
<mat-paginator [pageSizeOptions]="[5, 10, 25, 100]"></mat-paginator>
</div>
Table.component.ts:
import { Component, OnInit, ViewChild, ChangeDetectorRef,ElementRef} from '#angular/core';
import {MatPaginator, MatSort, MatTableDataSource} from '#angular/material';
import { WorkflowService } from "../workflow.service";
import { HttpClient } from '#angular/common/http';
import {DataSource} from '#angular/cdk/collections';
import * as XLSX from 'xlsx/xlsx';
#Component({
selector: 'app-table-doc',
templateUrl: './table-doc.component.html',
styleUrls: ['./table-doc.component.css']
})
export class TableDocComponent implements OnInit {
#ViewChild('TABLE') table: ElementRef;
#ViewChild(MatPaginator) paginator: MatPaginator;
#ViewChild(MatSort) sort: MatSort;
displayedColumns = ['MSID','MSPW','MSRequsest','ClassID','ClassName',
'FirstName','LastName','Email','Role','EmployeeRoleFrom','VendorID',
'VendorNameCompany','StaffID','Source','HireDate','HireType','EnteredDate',
'FloorDate','SiteLocation','EmployeeContractorID','TransferFrom','Notes','Status',
];
dataSource = new MatTableDataSource();
constructor( private http:HttpClient,private workflowService : WorkflowService,private changeDetectorRefs: ChangeDetectorRef) {
}
ngOnInit() {
this.tableDataSource();
}
ngAfterViewInit() {
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
applyFilter(filterValue: string) {
filterValue = filterValue.trim(); // Remove whitespace
filterValue = filterValue.toLowerCase(); // Datasource defaults to lowercase matches
this.dataSource.filter = filterValue;
}
tableDataSource(){
this.workflowService.GetUploadDocData().subscribe(
data => {
this.dataSource.data = data ;
}
);
}
ExportTOExcel()
{
const ws:XLSX.WorkSheet=XLSX.utils.table_to_sheet(this.table.nativeElement);
const wb:XLSX.WorkBook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');
console.log(this.table.nativeElement);
/* save to file */
XLSX.writeFile(wb, 'SheetJS.xlsx');
}
}
I am using npm i XLSX and getting some error.
ERROR:
Bad range (0): A1:A0
[object Error]{description: "Bad range (...", message: "Bad range (...", name: "Error", ngDebugContext: Object {...}, stack: "Error: Bad ..."}
what is wrong here?
is there any other way to export excel from Angular Material Table, I also need the pagination for my table.
SheetJS XLSX is not compatible with Angular Material 5 & above because it reads table tag where as from material 5 on wards the mat-table is used.
Too late, but I try...
I found the same problem and fixed this way:
Change HTML tags from
<mat-table...>...</mat-table> to <table mat-table...>...</table>
<mat-header-cell ...>...</mat-header-cell> to <th mat-header-cell....>...</th>
<mat-cell...>...</mat-cell> to <td mat-cell ...>...</td>
That's all, XLSX not recognize material tags, but the material attributes.

Resources