Data state change is not calli ng after applying filtering

Hi

I am using filtering(column menu), and DataStateChange event both in my grid.

 <ejs-grid #genericgrid id={{item.Name}} [dataSource]='genericGridData' rowHeight='38' [allowSelection]='true'
            height='190' width="100%" (rowDeselected)='rowDeselected($event)'
            [toolbar]='toolbar' (toolbarClick)='clickHandler($event)' (rowSelected)='rowSelected($event)'
            [contextMenuItems]='contextMenuItems' (contextMenuClick)='contextMenuClick($event)'
            allowSorting='true' showColumnMenu='true' allowGrouping='true'
            [filterSettings]='filterSettings' allowReordering="true"
            [allowPdfExport]='true' [allowExcelExport]='true' gridLines='Both'
            [allowPaging]='true' [pageSettings]='pageSetting' allowResizing='true'
            allowFiltering ='true' (dataStateChange)='dataStateChange($event)'
            (recordDoubleClick)='recordDoubleClick($event)'>

For DataSource, in .ts file, I am doing this:-

 this.genericGridData = data;
          this.gridDataSource = { result: data, count: data.length };

If I use gridDataSource  as dataSource then filtering is not working and its spinning endlessly 
and if I use genericGridData  as dataSource then dataStateChange is not calling.

Please help so that both can work.


Regards,
Namita

8 Replies 1 reply marked as answer

MS Manivel Sellamuthu Syncfusion Team April 22, 2021 11:56 AM UTC

Hi Namita, 
 
While using custom binding or Observable binding, the grid expects an object as the result of the custom logic and the emitted value should be an object with properties result and count. Also we have prepare a simple sample for your convenience. Please refer the below sample and screenshot for more information. 
 
 
Screenshot: 
 
 
 
 
 
 
 
For every grid actions(such as filter, page 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 data as result and count object.   
 
 
Note:  ‘dataStateChange’ event is not triggered at the Grid initial render. You need to call your remote service by manually with 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 send the default value as 12 ) in dataBound event of Grid. and please return the result like as “{result: […], count: …}” format to Grid. 
            
If you still faced the issue, please share the below details 
 
  1. Share the complete Grid code.
  2. Please try to replicate the issue  in the given sample.
  3. If possible, please share the simple issue replicable sample.
 
Regards, 
Manivel 


Marked as answer

NA Namita May 28, 2021 07:54 AM UTC

Hi
I am trying to replicate given example, but order.service.cs is not able to recognise. 
And when I am using it in my service , it is giving null:-

In service:-
Not working code:-

GetGridDataByStepId(StepId: number, UserRoleId: number, TransactionStatus: string, PageSize: number, PageNumber: number, sortdatafield: string, sortorder: string, FilterQuery: string, locale: string, timeZone: string, offSet: number): Observable<any> {
    return this.httpClient.get<any>(this.basrUrl + "/GenericGrid/GetGridDataByStepId?StepId=" + StepId + "&UserRoleId=" + UserRoleId + "&TransactionStatus=" + TransactionStatus + "&PageSize=" + PageSize + "&PageNumber=" + PageNumber + "&sortdatafield=" + sortdatafield + "&sortorder=" + sortorder + "&FilterQuery=" + FilterQuery + "&locale=" + locale + "&timeZone=" + timeZone + "&offSet=" + offSet)
      .pipe(map((response: any) => response.json()))
      .pipe(map((response: any) => (<DataResult>{
        result: response['d']['results'],
        count: parseInt(response['d']['__count'], 10)
      })))
      .pipe((data: any) => data);
  }

working code:-

GetGridDataByStepId(StepId: number, UserRoleId: number, TransactionStatus: string, PageSize: number, PageNumber: number, sortdatafield: string, sortorder: string, FilterQuery: string, locale: string, timeZone: string, offSet: number): Observable<any> {
    return this.httpClient.get<any>(this.basrUrl + "/GenericGrid/GetGridDataByStepId?StepId=" + StepId + "&UserRoleId=" + UserRoleId + "&TransactionStatus=" + TransactionStatus + "&PageSize=" + PageSize + "&PageNumber=" + PageNumber + "&sortdatafield=" + sortdatafield + "&sortorder=" + sortorder + "&FilterQuery=" + FilterQuery + "&locale=" + locale + "&timeZone=" + timeZone + "&offSet=" + offSet);
  }


In Html:-

 <ejs-grid #genericgrid id={{item.Name}} [dataSource]='genericGridData | async' rowHeight='38' [allowSelection]='true'
                          height='190' width="100%" (rowDeselected)='rowDeselected($event)'
                          [toolbar]='toolbar' (toolbarClick)='clickHandler($event)' (rowSelected)='rowSelected($event)'
                          [contextMenuItems]='contextMenuItems' (contextMenuClick)='contextMenuClick($event)'
                          allowSorting='true' showColumnMenu='true' allowGrouping='true'
                          [filterSettings]='filterSettings' allowReordering="true"
                          [allowPdfExport]='true' [allowExcelExport]='true' gridLines='Both'
                          [allowPaging]='true' [pageSettings]='pageSetting' allowResizing='true'
                          allowFiltering='true' (dataStateChange)='dataStateChange($event)'
                          (recordDoubleClick)='recordDoubleClick($event)'>


In ts:-
GetGridData(StepId) {
    debugger;
    this._service.GetGridDataByStepId(StepId, this.UserRoleId, this.transactionStatus, this.pagesize, 0, this.sortDataFieldName, this.sortOrder, "", this.locale, this.timeZone, this.offSet)
      .subscribe(
        data => {
          
          
           this.genericGridData = data;
          //this.gridDataSource = { result: data, count: data.length };

         
        }
      );
  }



Please help




NA Namita May 28, 2021 08:35 AM UTC

Hi, I want to update something:-

Now I am able to get data in service in result and count format. But Data is not visible in Grid while using "| async". 
If I am not using "| async" then it is giving data but filter doesn't work.

Here are some screenshot:-


Data is not coming:-



Another combination is:-


Data is coming:-



But filter is not working:-




If possible then we can have call also.

Thanks and Regards
Namita



MS Manivel Sellamuthu Syncfusion Team May 31, 2021 10:28 AM UTC

Hi Namita, 

Thanks for your update. 

From your update we can understand that We can understand that you are able to get the data in Grid while not using the “| async”. While checking the screenshot “filter is not working” we suspect that you have not handled the Excel Filter operations in the dataStateChange event. 

The dataStateChange event is triggered with appropriate arguments when the Excel filter requests the filter choice data source. You need to resolve the Excel filter data source using the dataSource resolver function from the state argument. Please refer the below documentation for more information. 

Please let us know if you need further assistance. 

Regards, 
Manivel 



NA Namita June 1, 2021 02:19 AM UTC

Hi

Now I am able to call server side state event with filter.
Thanks for your support.

Now I want to prepare filterquery. Please share an example of making filterquery so that I can pass it in database to filter data.


Namita


MS Manivel Sellamuthu Syncfusion Team June 1, 2021 10:09 AM UTC

Hi Namita, 
 
Thanks for your update. 
 
We are glad to hear that you are able to call server side state event with filter. 
 
We have prepared a simple sample based on your requirement. In which, we filter one value using checkboxes. On filtering, the dataStateChange event will be triggered with the filter queries (where), using these queries you can perform filtering in your service and return the filtered records in result and count format to the Grid. Refer to the below screenshot. 
 
 
public getData(state: DataStateChangeEventArgs): Observable<DataStateChangeEventArgs> { 
      let sortQuery: String = ''; 
      const skipquery = state.skip ? `$skip=${state.skip}` : null; 
      let pageQuery = ''; 
      const takeQuery = state.take ? `$top=${state.take}` : null; 
      if (skipquery) { 
        pageQuery = `${skipquery}&`; 
      } 
      if (takeQuery) { 
        pageQuery = `${pageQuery}${takeQuery}`; 
      } 
      let filterQuery: String = ''; 
      if ((state.sorted || []).length) { 
        sortQuery = `&$orderby=` + state.sorted.map((obj: Sorts) => { 
          return obj.direction === 'descending' ? `${obj.name} desc` : obj.name; 
        }).reverse().join(','); 
      } 
   
      if (state.where) { 
        filterQuery = `&$filter=` + state.where.map((obj) => { 
          return (<Predicate>obj).predicates.map((predicate) => { 
            return predicate.operator === 'equal' ? `${predicate.field} eq ${predicate.value}` : 
              `${predicate.operator}(tolower(${predicate.field}),'${predicate.value}')`; 
          }).reverse().join(' and '); 
        }); 
      } 
   
      return this.http 
        .get(`${this.BASE_URL}?${pageQuery}${sortQuery}${filterQuery}&$count=true`) 
        .pipe(map((response: any) => response.json())) 
        .pipe(map((response: any) => { 
          return state.dataSource === undefined ? (<DataResult>{ 
            result: response['value'], 
            count: parseInt(response['@odata.count'], 10), 
          }) : response['value']; 
        })) 
        .pipe(map((data: any) => data)); 
    } 
  } 
 
 
 
 
Please get back to us if you need further assistance with this. 
 
Regards, 
Manivel 



NA Namita June 4, 2021 03:07 AM UTC

I have done this. Thanks for your support.

Please close the thread.


MS Manivel Sellamuthu Syncfusion Team June 7, 2021 05:09 AM UTC

Hi Namita, 

Thanks for your update. 

We are glad that your requirement has been resolved. 

Regards, 
Manivel 


Loader.
Up arrow icon