We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date
close icon

How to fetch the data when the scrollbar reaches the end of the scroller in Angular Grid

Hi,
 I want to know the usage of infinite scrolling but with data fetched from backend i.e using api as we scroll to bottom infinitely,
As of now you provided a method for infinite scrolling when whole data fetched at initial time but my requirement is to fetch records as we scroll down using api. as we have odata options like $top,$skip queries.

27 Replies 1 reply marked as answer

RR Rajapandi Ravi Syncfusion Team August 5, 2020 02:03 PM UTC

Hi Goutham, 

Greetings from syncfusion support 

Based on your query we found that you like to fetch the data when the scrollbar reaches the end of the scroller. By default the infinite scrolling does not load the whole data initially.  

The infinite scrolling feature works like the lazy loading concept, which means the buffer data is loaded only when the scrollbar reaches the end of the scroller. To enable Infinite scrolling, set enableInfiniteScrolling property as true.  

Please refer the below code example and sample for more information. 

App.component.ts     
 
export class AppComponent { 
    public data: DataManager; 
    public initialPage: Object; 

    ngOnInit(): void { 
         this.data = new DataManager({ 
            url: 'https://js.syncfusion.com/demos/ejServices/Wcf/Northwind.svc/Orders', 
            adaptor: new ODataAdaptor(), 
            crossDomain: true 
        }); 
    } 
 



Screenshot: 

 


Regards, 
Rajapandi R

Marked as answer

AC Aparna Cilusani replied to Rajapandi Ravi November 26, 2021 11:13 AM UTC

how we need to call a api instead of url to get the data from the server




RR Rajapandi Ravi Syncfusion Team November 29, 2021 12:08 PM UTC

Hi Aparna, 

Thanks for the update 

Before proceeding with your query, we would like to share the available data-bindings in EJ2 Grid. 
 
If you are using WebAPI service or OData or SQL or any DataTable or List binding in your application, then we suggest you use Syncfusion inbuilt adaptor of DataManager to perform action on your service. 
 
You can choose the adaptors based on your Database. Refer to the below documentation which detailly illustrates available data adaptors in EJ2. 





For each Grid data-action like Filtering, Sorting, Paging, Scrolling etc., we send the correspond query to the server based on the data-adaptors. You can execute the queries with your data and return results with required format to the Grid. 
 
If you are using any custom service, we suggest you use custom-binding feature to bind the data to the Grid. We would like to share the behavior of custom-binding in EJ2 Grid. 

For every grid action(such as FilterPage, etc.,), we have triggered the dataStateChange event and, in that event arguments we have send the corresponding action details(like skip, take, filter field, value, sort direction, etc.,) based on that, you can perform the action in your service and return the data as a result and count object.  

Note: ‘dataStateChange’ event is not triggered at the Grid initial render. If you are using a remote service, you need to call your remote service by manually with a pagination query (need to set skip value as 0 and take value based on your pageSize of pageSettings in Grid. If you are not defined pageSize in pageSettings, you need to send the default value 12 ) in mounted. Please return the result like as “{result: […], count: …}” format to Grid. 

dataSourceChanged’ event is triggered when performing CRUD action in Grid. You can perform the CRUD action in your service using action details from this event and, you need to call the endEdit method to indicate the completion of save operation. 


                               https://ej2.syncfusion.com/angular/documentation/grid/observables/#perform-crud-operations 

 
If it does not meet your requirement, please share the details about what type of API you are binding in your application. 

Rajapandi R 



AC Aparna Cilusani replied to Rajapandi Ravi November 30, 2021 08:33 AM UTC

Hi Rajapandi Ravi,


Thank you for your reply. 


How do we get, on scroll event in infinite scrolling. I want to fetch the data from custom service on end of every scroll. 



RR Rajapandi Ravi Syncfusion Team December 1, 2021 12:53 PM UTC

Hi Aparna, 
 
Thanks for the update 

In EJ2 Grid Infinite scrolling for each time scrolling request will be send to the server. 

From your update, we could see that you are using custom binding (Observable binding). We have prepared sample with infinite scrolling with custom binding. In that sample the dataStateChange event will be triggered for each grid action like paging, sorting, filtering, etc., with the arguments. By using these arguments, you can execute your own service and return the data to the grid with the result and count pair. Please refer the below code example and sample for better understanding. 

[App.component.html] 
<div class="control-section"> 
    <ejs-grid [dataSource]='data | async' #grid [height]=400 [enableInfiniteScrolling]='true' [pageSettings]='pageOptions' (dataStateChange)= 'dataStateChange($event)'> 
        <e-columns> 
            <e-column field= "OrderID" headerText="Order ID" width="130" ></e-column> 
            <e-column field= "CustomerID" headerText="Customer Name" width="150"></e-column> 
            <e-column field= "ShipName" headerText="Ship Name" width="200"></e-column> 
            <e-column field= "ShipCity" headerText="Ship City" width="150"></e-column> 
        </e-columns> 
    </ejs-grid> 
</div> 
[App.component.ts] 
import { ComponentOnInitInject,ViewChild } from '@angular/core'; 
import { Observable } from 'rxjs'; 
import { OrdersService } from './order.service'; 
import { DataStateChangeEventArgs,PdfExportProperties,ExcelExportProperties,ToolbarItems,IFilter,Filter } from '@syncfusion/ej2-grids'; 
import { GridComponent } from '@syncfusion/ej2-angular-grids'; 
import { ClickEventArgs } from '@syncfusion/ej2-navigations' 
 
@Component({ 
    selector: 'app-root', 
    templateUrl: 'app.component.html', 
    providers: [OrdersService], 
}) 
export class AppComponent { 
    public data: Observable<DataStateChangeEventArgs>; 
    public pageOptions: Object; 
    public count = 0; 
    public printData: Object[]; 
    @ViewChild('grid', {statictrue}) 
    public grid: GridComponent; 
    public state: DataStateChangeEventArgs; 
    public toolbarOptions: ToolbarItems[]; 
    constructorpublic service: OrdersService) { 
        this.data = service; 
    } 
 
    public dataStateChange(state: DataStateChangeEventArgs): void { 
// for each time the scroller reaches the end this event will be invoked  
with the parameters of skip and take  
// here instead using the service you can apply the data and return as result and count here 
        this.service.execute(state); 
    } 
 
    public ngOnInit(): void { 
        this.pageOptions = { pageSize: 50 }; 
// for initial rendering define the records to binding the Grid 
        let state = { skip: 0, take: 50 }; 
        this.service.execute(state); 
    } 
} 
 
[OrderService.ts] 
import { Injectable } from '@angular/core'; 
import { Http } from '@angular/http'; 
import { DataStateChangeEventArgsSortsDataResult } from '@syncfusion/ej2-angular-grids' 
import { Observable } from 'rxjs'; 
import { Subject } from 'rxjs'; 
import { map } from 'rxjs/operators'; 
 
@Injectable() 
export class OrdersService extends Subject<DataStateChangeEventArgs> { 
    private BASE_URL = 'https://js.syncfusion.com/demos/ejServices/Wcf/Northwind.svc/Orders' 
 
    constructor(private http: Http) { 
        super(); 
    } 
 
    public execute(state: any): void { 
        this.getData(state).subscribe(x => super.next(x)); 
    } 
 
    public getData(state: DataStateChangeEventArgs): Observable<DataStateChangeEventArgs> { 
      console.log(state.action) 
        const pageQuery = `$skip=${state.skip}&$top=${state.take}`; 
        let sortQuery: string = ''; 
 
        if ((state.sorted || []).length) { 
            sortQuery = `&$orderby=` + state.sorted.map((obj: Sorts) => { 
                return obj.direction === 'descending' ? `${obj.name} desc` : obj.name; 
            }).reverse().join(','); 
        } 
 
        return this.http  
           .get(`${this.BASE_URL}?${pageQuery}${sortQuery}&$inlinecount=allpages&$format=json` 
           .pipe(map((response: any) => response.json())) 
           .pipe(map((response: any) => (<DataResult>{ 
// here we are returning the 50 records to be displayed in the Grid 
                result: response['d']['results'], 
                count: parseInt(response['d']['__count'], 10) 
// here we are returning the data as Object of result and count 
        }))) 
        .pipe((data: any) => data); 
    } 
} 


Refer the below which illustrates the limitations of infinite scrolling and observables binding.
https://ej2.syncfusion.com/angular/documentation/grid/infinite-scroll/#limitations-for-infinite-scrolling 

Please get back to us if you need further assistance on this. 

Regards, 
Rajapandi R 



GH Ganesh Harihar June 15, 2022 11:10 AM UTC

Hello Rajapandi Ravi,

I have implemented the above example but I have to add filtering functionality with the type 'Menu' and filter 'CheckBox' but after clicking on the filter icon it's just showing loader it's not able to get all the values for the filtering. Can't it just show all the loaded values for that column?

Here is the Url of implementation: https://stackblitz.com/edit/angular-infine-scroll-custombinding-r8yc4e?file=app.component.html

Thanks in advance.

Regards,

Ganesh Harihar



RR Rajapandi Ravi Syncfusion Team June 16, 2022 02:15 PM UTC

Hi Ganesh,


Thanks for the update.


Currently, we are validating your query with your shared information, and we will update you the details on or before 20th June 2022. Until then we appreciate your patience.


Regards,

Rajapandi R



RR Rajapandi Ravi Syncfusion Team June 20, 2022 12:28 PM UTC

Hi Ganesh,


Thanks for your patience


In custom binding when the filter/sort/page actions are performed in the Grid, the action details will be returned in the dataStateChange event as shown in the below image(shows filter action details),



From this event you need to form the filter/page/sort queries in the format as required by your server, process the action and bind the result to the Grid dataSource as an object of ‘result’ and ‘count’.


More details on custom binding can be checked in the below documentation link,


Custom binding: https://ej2.syncfusion.com/angular/documentation/grid/observables/#handling-grid-actions


Regards,

Rajapandi R



GH Ganesh Harihar June 21, 2022 09:45 AM UTC

Hello Rajapandi Ravi,

Thank you for the response but if you have noticed I did the same thing in sample prepared after clicking on the filter icon it throws an error. Following is the sample URL if possible edit that sample and make filters work on 'Customer Name' column.

https://stackblitz.com/edit/angular-infine-scroll-custombinding-r8yc4e?file=app.component.html

Attached screenshot of the error also.

Regards,

Ganesh Harihar


Attachment: Filter_Error_11dc6654.zip


RR Rajapandi Ravi Syncfusion Team June 22, 2022 01:23 PM UTC

Hi Ganesh,


Thanks for the update.


We have checked your query and we could see that you like to use the Excel Filter in the Custom binding. For every grid action(such as FilterPage, etc.,), we have triggered the dataStateChange event and, in that event arguments, we have sent the corresponding action details(like skip, take, filter field, value, sort direction, etc.,) based on that, you can perform the action in your service and return the data as a result and count object.   


dataStateChange: https://ej2.syncfusion.com/angular/documentation/api/grid/#datastatechange


 

[app.component.ts] 

 

 

  public dataStateChange(state) { 

      // exectue your own service and perform the action with state queries and return the result and count data to the Grid 

      this.getAsyncData(state); 

    } 

  } 

 

  getAsyncData(state) { 

    if (state.where) { 

      var gridqueries = this.grid.getDataModule().generateQuery().queries

      var wherequery

      for (var i = 0i < gridqueries.lengthi++) { 

        if (gridqueries[i].fn == 'onWhere') { 

          wherequery = gridqueries[i].e

        } 

      } 

      new DataManager({ url: SERVICE_URIadaptor: new ODataAdaptor() }) 

        .executeQuery(new Query().where(wherequery).take(state.take).skip(state.skip)) 

        .then((eany=> { 

         // bind the result and count object to the Grid 

          this.grid.dataSource = { 

            result: e.actual['d']['results'], 

            count: parseInt(e.actual['d']['__count'], 10) 

          }; 

          return e

        }); 

    } else { 

      new DataManager({ url: SERVICE_URIadaptor: new ODataAdaptor() }) 

        .executeQuery(new Query().take(state.take).skip(state.skip)) 

        .then((eany=> { 

         // bind the result and count object to the Grid 

          this.grid.dataSource = { 

            result: e.actual['d']['results'], 

            count: parseInt(e.actual['d']['__count'], 10) 

          }; 

          return e

        }); 

    } 

  } 

 

 


Note: ‘dataStateChange’ event is not triggered at the Grid initial render. If you are using a remote service, you need to call your remote service by manually with a pagination query (need to set skip value as 0 and take value based on your pageSize of pageSettings in Grid. If you are not defined pageSize in pageSettings, you need to send the default value 12 ) in ngOnInIt. Please return the result like as “{result: […], count: …}” format
to Grid.  

 

[app.component.ts] 

 

 

  public ngOnInit(): void { 

    // load initial data by executing your own service with page query and bind result and count value to the Grid 

    new DataManager({ url: SERVICE_URIadaptor: new ODataAdaptor() }) 

      .executeQuery(new Query().take(12).skip(0).expand(['Employee']) 

      ) 

      .then((eany=> { 

        // bind the current page data to the grid dataSource with result and object format 

        this.grid.dataSource = { 

          result: e.actual['d']['results'], 

          count: parseInt(e.actual['d']['__count'], 10) 

        }; 

      }); 

  } 

 

 

When you open the filter dialog, the dataStateChange event with requestType (‘filterchoicerequest/stingfilterrequest’) will be triggered. In that event, you need to execute your service and bind the array of object to the state.dataSource method. 

When you search the value in the filter dialog, the dataStateChange event with requestType (‘filtersearchbegin’) will be triggered. In that event, you need to filter the value from your service based on the event argument and bind the array of objects to the state.dataSource method. 

 

[app.component.ts] 

 

  public dataStateChange(state) { 

    if ( 

      state.action && 

      (state.action.requestType == 'filterchoicerequest' || 

        state.action.requestType == 'filtersearchbegin' || 

        state.action.requestType == 'stringfilterrequest'

    ) { 

   // below code will be executed when open the filter dialog and perform search in the filter dialog 

      state.skip = 0

      // execute your service and bind the data for other columns 

      if (state.where) { 

        new DataManager({ url: SERVICE_URIadaptor: new ODataAdaptor() }).executeQuery

            new Query().where( state.where[0].field, state.where[0].operator, state.where[0].value

          ).then((eany=> { 

            // bind array of Objects 

            state.dataSource(e.result); 

          }); 

      } else { 

        new DataManager({ url: SERVICE_URIadaptor: new ODataAdaptor() }) 

          .executeQuery(new Query()) 

          .then((eany=> { 

            // bind array of Objects 

            state.dataSource(e.result); 

          }); 

      } 

    } else { 

      // exectue your own service and perform the action with state queries and return the result and count data to the Grid 

      this.getAsyncData(state); 

    } 

  } 

 

Find the below sample and documentation for your reference. 


Sample: https://stackblitz.com/edit/angular-ws2fqv-mxcxjs?file=app.component.html,app.component.ts


Custom-Binding: https://ej2.syncfusion.com/angular/documentation/grid/observables/


Excel Filtering in Custom-Binding: https://ej2.syncfusion.com/angular/documentation/grid/observables/#provide-excel-filter-data-source                            


Regards,

Rajapandi R



GH Ganesh Harihar June 27, 2022 05:52 AM UTC

Hello Rajapandi Ravi,

Thanks for the guidance and prepared sample.


Regards,

Ganesh Harihar



RR Rajapandi Ravi Syncfusion Team June 28, 2022 06:44 AM UTC

Most Welcome.



GH Ganesh Harihar July 5, 2022 09:05 AM UTC

Hello Rajapandi Ravi,

I have checked the prepared sample and tried to implement but I get to know that when we are fetching data to show in the filter popup we get all the records. which is not a great choice because of the time required for getting all the records from the database. 

Is there any way we can apply virtual scroll with pagination for getting filter popup values or can we create a custom filter popup?

Regards,

Ganesh Harihar



RR Rajapandi Ravi Syncfusion Team July 6, 2022 12:49 PM UTC

Hi Ganesh,


Thanks for the update.


By default, in our EJ2 Grid the Virtualization works without Paging, The Virtualization feature is used to render the rows on scrolling content and Paging feature is used to render the rows on navigating to another page. Both are different features; we have to use only one feature at a time in the Grid. So, you cannot use the Paging feature with the Virtualization option. As a result, combining Virtualization and Paging is not a valid case.


Regards,

Rajapandi R



GH Ganesh Harihar July 7, 2022 05:22 AM UTC

Hello Rajapandi Ravi,

That's correct but I want to fetch the first 10 records initially from the server. if the user scrolls down will call an API  with page index 1 and get the next 10 records and merge the first 10 records and the next 10 records and assign them to the data and so on for other records.

Regards,

Ganesh Harihar



RR Rajapandi Ravi Syncfusion Team July 8, 2022 12:30 PM UTC

Hi Ganesh,


Thanks for your update


Our provided sample works like the same behavior you want “if the user scrolls down will call an API with page index 1 and get the next 10 records and merge the first 10 records”. Please share the sample and video demo for more information.


Sample: https://stackblitz.com/edit/angular-ws2fqv-zwxqgb?file=app.component.html,app.component.ts


Video demo: https://www.syncfusion.com/downloads/support/directtrac/general/ze/scroll-463552276.zip


Regards,

Rajapandi R



GH Ganesh Harihar July 13, 2022 06:06 AM UTC

Hello Rajapandi Ravi,

It works for getting records of the grid but I am talking about values in the filter popup.

Regards,

Ganesh Harihar



RR Rajapandi Ravi Syncfusion Team July 14, 2022 01:48 PM UTC

Hi Ganesh,


Currently we are validating query with your shared information, and we will update you the details on or before 18th July 2022. Until then we appreciate your patience.


Regards,

Rajapandi R



RR Rajapandi Ravi Syncfusion Team July 18, 2022 12:51 PM UTC

Hi Ganesh, 


Since you like to fetch the records while scrolling in the filter popup , So we have logged a feature task as “OnDemand concept for Checkbox, Excel Filter Type” for this requirement. At Syncfusion, we are committed to fixing all validated defects (subject to technical feasibility and Product Development Life Cycle ). This feature will be included in any of our upcoming release. 


You can now track the current status of your request, review the proposed resolution timeline, and contact us for any further inquiries through this link.  


Feedback Link : https://www.syncfusion.com/feedback/34647/ondemand-concept-for-checkbox-excel-filter-type


Regards,

Rajapandi R



GH Ganesh Harihar July 21, 2022 06:57 AM UTC

Hello Rajapandi Ravi,

Thanks for the response.

Regards,

Ganesh Harihar



RR Rajapandi Ravi Syncfusion Team July 22, 2022 06:02 AM UTC

Hi Ganesh,


Most Welcome


Regards,

Rajapandi R



GU Gustav November 17, 2022 01:24 PM UTC

Hello,
I'm having a problem with fetching new data, whenever new data comes in it calls actionBegin of requestType=refresh, and I loose the state of what has been selected and it scrolls to the top and it resets back to first 75 rows which is my the initial state of the grid.
How can I prevent this or any workarounds?


Note I have this as my columns are auto-generated,

if (this.addColumn) {
var obj = { type: 'checkbox', width: 50 };
this.grid.columns.unshift(obj as any);
this.addColumn = false;
(this.grid.columns[1] as any).isPrimaryKey = true;
this.grid.freezeRefresh();
}


This is my grid:

<ejs-grid
#grid
#grids
height="100%"
width="100%"
[dataSource]="tableService.facade.all$ | async"
[allowFiltering]="true"
[filterSettings]="filterOptions"
[editSettings]="editSettings"
[allowMultiSorting]="true"
[allowSorting]="true"
(actionComplete)="actionComplete($event)"
(dataBound)="dataBound($event)"
[selectionSettings]="selectionOptions"
[allowSelection]="true"
(actionBegin)="action($event)"
[enableInfiniteScrolling]="true"
[pageSettings]='pageSettings'
(created)="created($event)"
>


I have been trying to make it work like this:

    let toolbar: HTMLElement =
      this.grid.element.querySelector('.e-gridcontent');
    let tableGrid: HTMLElement = toolbar.querySelector('.e-content');
        tableGrid.scrollTo(0, tableGrid.scrollHeight - 300);


but it doesn't seem to work just right.





RR Rajapandi Ravi Syncfusion Team November 30, 2022 01:08 PM UTC

Gustav,


Before we start providing solution to your query, we need some information for our clarification. So, please share the below details that will be helpful for us to provide better solution.


1)          Please share your exact requirement scenario with detailed description.


2)          Please share your complete Grid rendering code, in your Grid you are binding the events, so we would like to check the events and complete codes.


3)          Share your syncfusion package version.


4)          Share the issue scenario in video demonstration format.



GU Gustav December 1, 2022 03:41 PM UTC

Hi,
So the problem that I'm having is when I fetch new data with infinite scrolling, when it fetches new data it resets the table and it leaves me at the top of the table with only the first initial rows that are rendered in the beginning.
I'm also using NGRX.

grid.html:

  <ejs-grid
  id="elem"
  #grid
  #grids
  height="100%"
  width="100%"
  [dataSource]="tableService.facade.all$ | async"
  [allowFiltering]="true"
  [filterSettings]="filterOptions"
  [editSettings]="editSettings"
  [allowMultiSorting]="true"
  [allowSorting]="true"
  [toolbar]="toolbar"
  (actionComplete)="actionComplete($event)"
  (dataBound)="dataBound($event)"
  [selectionSettings]="selectionOptions"
  [allowSelection]="true"
  [showColumnChooser]="showColumnChooser"
  (toolbarClick)="toolbarClick($event)"
  (actionBegin)="action($event)"
  [enableInfiniteScrolling]="true"
  [infiniteScrollSettings]="infiniteOptions"
  (dataStateChange)='dataStateChange($event)'
  [pageSettings]='pageSettings'
  (created)="created($event)"
  locale='de-DE'
  >


grid.ts :

 

@Component({
  selector: 'app-table',
  templateUrl: './grid.component.html',
  styleUrls: ['./grid.component.css'],
  encapsulation: ViewEncapsulation.None,
  providers: [InfiniteScrollService, ToolbarService, PdfExportService],
})
export class GridTableComponent implements OnInit {
  @ViewChild('grid', { static: true }) public grid: GridComponent;
  @Output() public fetchMore: EventEmitter<void> = new EventEmitter();

  inputMessageRef: ElementRef;
  editSettings: EditSettingsModel;
  toolbar: ToolbarItems[];
  selectionOptions: SelectionSettingsModel;
  filterOptions: FilterSettingsModel;
  pageSettings: PageSettingsModel;
  infiniteOptions: InfiniteScrollSettingsModel;
  public state: DataStateChangeEventArgs;
  test = true;
  columns: any;
  data;
  filtered = [];
  refreshed = false;
  flag = true;
  scrollFlag = true;
  isWeb: boolean;
  title: string;
  startIndex = this.tableService.paging;
  totalPageable: number;
  public addColumn: boolean = true;
  public loadingIndicator;
  showColumnChooser: boolean = true;
  constructor(
    private router: Router,
    public tableService: TableService,
    private translate: TranslateService,
    private formService: FormService,
    private loadingService: LoadingService
  ) {}

  ngOnInit() {

    this.pageSettings = { pageSize: 25, pageSizes: false };
    this.selectionOptions = {
      checkboxMode: 'ResetOnRowClick',
      type: 'Multiple',
      mode: 'Both',
    };
    this.filterOptions = { type: 'Menu' };
    // this.tableModel(this.data);

    this.infiniteOptions = {};

      this.editSettings = {
        allowEditing: true,
        allowAdding: true,
        allowDeleting: true,
        mode: 'Normal',
      };
      this.toolbar = [
        'Search',
        'Add',
        'Edit',
        'Delete',
        'Update',
        'Cancel',
        'PdfExport',
        'ColumnChooser',
      ];

      this.toolbar = ['Search', 'PdfExport', 'ColumnChooser'];
    }
    this.startIndex = this.tableService.paging - 25; // SHould be the same number as pageSettings -> pageSize
  }


  dataBound(args: any) {
    if (this.flag) {
      this.flag = false;
      // const column: ColumnModel = this.grid.getColumnByField('checkbox');
      // column.isPrimaryKey = true;
      this.filtered = this.data.columns.filter((item) => {
        for (var col in this.grid.columns) {
          if (item.key === undefined || item.key == col['field']) return false;
        }
        return true;
      });
      for (const cols of this.grid.columns) {
        (cols as any).visible = false;
        this.filtered.forEach((column: TableColumn) => {
          if ((cols as any).type === 'checkbox') {
            (cols as any).hideAtMedia = '(min-width: 70px)';
            (cols as any).visible = true;
            (cols as any).allowEditing = false;
            (cols as any).allowSorting = false;
            (cols as any).allowSearching = false;
            (cols as any).allowFiltering = false;
            (cols as any).allowReordering = false;
            (cols as any).showInColumnChooser = false;
            (cols as any).width = 'auto';
          }
          if (
            (cols as any).field === column.key &&
            (cols as any).field !== 'checkbox'
          ) {
            (cols as any).visible = true;
            // (cols as any).width = column.width;
            (cols as any).width = 'auto';
            (cols as any).headerText = this.translate.instant(column.label);
            // (cols as any).headerText = column.label;
            (cols as any).allowEditing = column.allowEditing;
          }
          return true;
        });
      }
      this.grid.refresh();
    }
    if (this.addColumn && this.data.checkbox) {
      var obj = { type: 'checkbox', width: 50 };
      this.grid.columns.unshift(obj as any);
      this.addColumn = false;
      (this.grid.columns[1] as any).isPrimaryKey = true;
      this.grid.freezeRefresh();
    }
  }



  action(args) {

    if (
      args.requestType == 'infiniteScroll' &&
      args.startIndex == this.startIndex
    ) {
      console.log('emited');
      this.startIndex += this.tableService.paging;
      this.scrollFlag = false;
      this.fetchMore.emit();
      this.scrollFlag = true;
    }
  }
}



this.fetchMore emitter is what triggers a call to backend. and what it loads the new data.


On the file that I have attached below its what happens after I reach the end and when the call is made.


Attachment: SyncFusion_Grid_problem_8839ac1c.zip


RR Rajapandi Ravi Syncfusion Team December 21, 2022 03:27 PM UTC

Gustav,


From your shared information we could see that in dataBound event, you are invoking refresh() & freezeRefresh() method of Grid. When you reach the bottom and the infinite scrolling fetch the next page records and then the dataBound event gets triggered, since you are invoking refresh() & freezeRefresh() method the entire Grid will get refreshed. So only the scroller was moved to the top again, it was the cause of the problem.


Please share the details about what you are trying to achieve in the dataBound event, please share your requirement scenario with detailed description.



GU Gustav January 11, 2023 01:19 PM UTC

Hi,

It's true in the dataBound event I invoke both of them, but I have a if() that it goes only once in that function.

But I'm seeing this in actionBegin() after I get an args.requestType of infiniteScroll event then the event as shown in the screenshot takes place and then it refreshes everything.




Which I cannot find a way to stop it.



JC Joseph Christ Nithin Issack Syncfusion Team March 3, 2023 05:08 AM UTC

Gustav,


  Before proceeding to the solution, we would like you to share the below details.


  • Explain your requirement in detail.
  • Complete grid rendering code.
  • Video demo of the issue you are facing.
  • Replication procedure of the issue your are facing.
  • Simple sample to replicate the issue.
  • Syncfusion package version.

Loader.
Up arrow icon