I am trying to build a data-grid library by wrapping ag-grid, so that if client decides to change ag-grid to some other library we dont have to work on multiple pages on refactoring. We can just make changes in library itself and use the new library.
Hierarchy
To implement SSRM, and externalize the API request and response mapping, I designed the component like this
getPosts(page: any, pageSize: any) {
this.http.get(
`https://jsonplaceholder.typicode.com/posts?_page=${page}&_limit=${pageSize}`
);
}
postsApi(params: any) {
const page = params.request.startRow / this.pageSize;
const pageSize = this.pageSize;
console.log("App",this);
this.service.getPosts(page, pageSize);
}
mapper(resposne: any) {
return {
rowData: resposne.data,
rowCount: resposne.pageInformation.totalRecord,
};
}
<uui-advanced-data-grid
[mode]="mode"
[header]="header"
[data]="data"
[sorting]="true"
[dragging]="true"
[pagination]="true"
[pageSize]="3"
[pageSizes]="[3, 10, 20, 50]"
[dataSource]="postsApi"
[mapper]="mapper"
></uui-advanced-data-grid>
@Input() dataSource!: any;
@Input() mapper!: any;
onGridRady(e: any) {
this.gridApi = e.api;
this.gridApi.setServerSideDatasource(this.getServerSideDatasource());
}
getServerSideDatasource(): IServerSideDatasource {
return {
getRows: (params: any) => {
console.log('ADG', this);
this.dataSource(params).subscribe(
(resposne: any) => {
params.success(this.mapper(resposne));
},
(error: any) => {
params.fail();
}
);
},
};
}
When data-grid component invokes subscribe on dataSource
, it internally calls the service method getPosts
from the this
reference of datagrid component, but it should actual look up this method in App component..
How can I configure this in a way, so that when data-grid invokes the passed dataSource
, it call the service from the parent component and not from data datagrid component? How can I still access this reference ofservice class used in a method which passed to child component from parent?
Finally figured it out. I knew about differences between functions and arrow functions. But this post gave me a deeper understanding.
Are 'Arrow Functions' and 'Functions' equivalent / interchangeable?
postApi
is declared as function (should have been arrow function), so when its calling the service class method with this
, it was using the reference of AdvancedDataGrid
.
I changed the postApi
to arrow function
postsApi = (params: any) => {
const page = params.request.startRow / this.pageSize;
const pageSize = this.pageSize;
console.log("App",this);
this.service.getPosts(page, pageSize);
}
Also I had an error in service class, I forgot to add return
getPosts(page: any, pageSize: any) {
return this.http.get(
`https://jsonplaceholder.typicode.com/posts?_page=${page}&_limit=${pageSize}`
);
}
Now it works like a charm