In my Angular-13 project I am trying to implement Advance Search in @tusharghoshbd/ngx-datatable
I have this code:
interface:
export interface Merchant {
id?: number;
merchant_name?: string;
account_number?: string;
merchant_status?: number;
created_date?: string;
}
service:
import { Merchant} from 'src/app/models/merchants.model';
getAllMerchants(): Observable<Merchant[]> {
return this.http.get<Merchant[]>(this.baseUrl 'merchants');
}
component.ts:
import { MerchantService } from 'src/app/services/merchant.service';
import { Merchant} from 'src/app/models/merchants.model';
export class MerchantsComponent implements OnInit {
@ViewChild('idTpl', { static: true }) idTpl!: TemplateRef<any>;
allMerchantList: any[] = [];
data = [];
dataBK = this.allMerchantList;
options = {};
columns: any = {};
constructor(
private merchantService: MerchantService,
) { }
ngOnInit(): void {
this.loadDatatable();
this.loadAllMerchants();
}
loadDatatable(){
this.columns = [
{
key: 'id',
title: '<div ><i ></i> SN.</div>',
width: 60,
sorting: true,
cellTemplate: this.idTpl,
},
{
key: 'merchant_name',
title: '<div ><i ></i> Merchant</div>',
width: 100,
sorting: true,
},
{
key: 'account_number',
title: '<div ><i ></i> Account No.</div>',
width: 100,
sorting: true
}
];
}
loadAllMerchants(){
this.merchantService.getAllMerchants().subscribe({
next: (res: any) => {
this.allMerchantList = res.result;
this.dataBK = this.allMerchantList;
}
})
}
onMerchantNameSearch(value: any)
{
this.data = this.dataBK.filter(row => row.merchant_name.toLowerCase().indexOf(value) > -1);
}
onAccountNumberSearch(value: any)
{
this.data = this.dataBK.filter(row => row.account_number.toLowerCase().indexOf(value) > -1);
}
}
component.html:
<div >
<div >
<label for="merchant_Name">Merchant Name:</label>
<input type="text" autocomplete="off" (input)="onMerchantNameSearch($event.target.value)" id="merchant_Name" placeholder="Merchant Name"/>
</div>
</div>
<div >
<div >
<label for="account_number">Account No.</label>
<input type="text" autocomplete="off" (input)="onMerchantNameSearch($event.target.value)" id="account_number" placeholder="Account Number"/>
</div>
</div>
<ngx-datatable tableClass="table table-striped table-bordered table-hover" [data]="allMerchantList" [columns]="columns" [options]="options">
<ngx-caption>
</div>
</ngx-caption>
<ng-template #addressTpl let-row let-rowIndex="rowIndex" let-columnValue="columnValue">
</ng-template>
<ng-template #idTpl let-rowIndex="rowIndex" let-row="row">
{{rowIndex 1}}
</ng-template>
</ngx-datatable>
console.log(res);
gives:
"result":[
{
"id": 1,
"merchant_name": "Appiah",
"account_number": "332222",
"merchant_status": 1,
"created_date": "2022-01-24T12:51:08.19",
},
{
"id": 2,
"merchant_name": "Kwesi",
"account_number": "554444",
"merchant_status": 1,
"created_date": "2022-01-25T16:43:41.873",
},
{
"id": 3,
"merchant_name": "fggffgfgfg",
"account_number": "455654",
"merchant_status": 1,
"created_date": "2022-01-25T16:46:20.77",
}
]
and
console.log(this.allMerchantList);
gives:
[
{
"id": 1,
"merchant_name": "Appiah",
"account_number": "332222",
"merchant_status": 1,
"created_date": "2022-01-24T12:51:08.19",
},
{
"id": 2,
"merchant_name": "Kwesi",
"account_number": "554444",
"merchant_status": 1,
"created_date": "2022-01-25T16:43:41.873",
},
{
"id": 3,
"merchant_name": "fggffgfgfg",
"account_number": "455654",
"merchant_status": 1,
"created_date": "2022-01-25T16:46:20.77",
}
]
As I enter values on the input fields in the Advance Search, I expect the result in the @tusharghoshbd/ngx-datatable.
But before I even do that at all, I got this error in the component:
error TS2339: Property 'merchant_name' does not exist on type 'never'.
192 this.data = this.dataBK.filter(row => row.merchant_name.toLowerCase().indexOf(value) > -1);
How do I resolve this?
Thanks
CodePudding user response:
Maybe don't use the dot-notation to get an property of an anonymous object. It could be, that the compiler sees this case wrong.
onMerchantNameSearch(value: any)
{
this.data = this.dataBK.filter(row =>
row['merchant_name'].toLowerCase().indexOf(value) > -1);
}
onAccountNumberSearch(value: any)
{
this.data = this.dataBK.filter(row =>
row['account_number'].toLowerCase().indexOf(value) > -1);
}
If you don't want to run into errors like that (and it seem to be a little problem of the TypeScript convert), then you could disable "strictNullChecks" in your angular.json file. Then the type "never" wouldn't be existent.
Your MerchantService is probably not correct. HttpClient.get directly returns the body, except when you are adding the options parameter and set the "observe"-propery. So try changing the subscription as follows:
this.merchantService.getAllMerchants().subscribe((res: any) => {
this.allMerchantList = res;
this.dataBK = this.allMerchantList;
})
Also have a look into my example: https://stackblitz.com/edit/angular-rrdq9z?file=src/app/app.component.ts
CodePudding user response:
Because you are assigning instance to null. You should initialize the property by defining it first. On row your trying to access merchant_name but it may never be there or have anything.
Quick and easy fix could be to define what dataBK has.
dataBK: any[] = [];
If we don't care what it has or data type may change we can just use any.
Proper way would to create an interface. What dataBK holds? An array of Rows. Okay - what kind of Rows? We include merchant_name, account_number... in row objects. Then we always know, that dataBK will hold an array or Row objects. And we have defined, that Row object will have such properties to be accessed. Leaving in the ? as I can't be 100% sure they will be there to be accessed, maybe you do - in case you can remove the questions marks.
dataBK: Row[] = [];
interface Row {
id?: number;
merchant_name?: string;
account_number?: string;
merchant_status?: number;
created_date?: string;
}
