RadzenDataGrid PageSizeChange event triggers after LoadData #1541

Closed
opened 2026-01-29 17:55:09 +00:00 by claunia · 2 comments
Owner

Originally created by @eirgje on GitHub (Dec 19, 2024).

Describe the bug
We are connecting an API with pagination to a RadzenDataGrid, our LoadData mapping trigger a new request to the API.
The PageSizeOptions being mapped triggers a secondary LoadData call before all the internal properties can be set and returned to the API request parameters. This requires us to create a mapping to the PageSizeChanged event and trigger a secondary API request.

When holding a reference to the RadzenDataGrid through ref we can find the expected value, but the methods and properties we can bind to on the RadzenDataGrid is acting after the LoadData event resulting in the PageSize property mapped being one event behind the actual PageSize selected by the user.

To Reproduce
Steps to reproduce the behavior:

  1. Create a RadzenDataGrid
  2. Map the following:

Attempt 1:

<RadzenDataGrid class="w-100 h-100 overflow-hidden"
                    TItem="ApiResponse"
                    Density="Density.Compact"
                    ExpandMode="@DataGridExpandMode.Single"
                    AllowColumnResize="@true"
                    AllowColumnPicking="@true"
                    AllowPaging="@true"
                    PagerAlwaysVisible="@true"
                    PagerHorizontalAlign="@HorizontalAlign.Center"
                    ShowPagingSummary="@true"
                    Page="@PageChanged"

                    @bind-PageSize="@CurrentPageSize"
                    PageSizeOptions="@PageSizeOptions"
                    LoadData="@LoadDataAsync"

                    IsLoading="@IsLoading"
                    GotoFirstPageOnSort="@true"
                    Sort="@(args =>  Sort(args.SortOrder.ToStringValue(), args.Column.GetSortProperty()))"
                    Data="@Data"
                    AllowSorting="@true"
                    AllowFiltering="@true"
                    PagingSummaryFormat="@.DataGridPagerSummary"
                    PageSizeText="@DataGridPageSizeSummary"
                    ColumnsShowingText="@.DataGridColumnsSummary">

Attempt 2:

<RadzenDataGrid class="w-100 h-100 overflow-hidden"
                    TItem="ApiResponse"
                    Density="Density.Compact"
                    ExpandMode="@DataGridExpandMode.Single"
                    AllowColumnResize="@true"
                    AllowColumnPicking="@true"
                    AllowPaging="@true"
                    PagerAlwaysVisible="@true"
                    PagerHorizontalAlign="@HorizontalAlign.Center"
                    ShowPagingSummary="@true"
                    Page="@PageChanged"

                    PageSizeChanged="@PageSizeChanged"
                    PageSize="@CurrentPageSize"
                    PageSizeOptions="@PageSizeOptions"
                    LoadData="@LoadDataAsync"

                    IsLoading="@IsLoading"
                    GotoFirstPageOnSort="@true"
                    Sort="@(args =>  Sort(args.SortOrder.ToStringValue(), args.Column.GetSortProperty()))"
                    Data="@Data"
                    AllowSorting="@true"
                    AllowFiltering="@true"
                    PagingSummaryFormat="@.DataGridPagerSummary"
                    PageSizeText="@DataGridPageSizeSummary"
                    ColumnsShowingText="@.DataGridColumnsSummary">
                    
private async Task PageSizeChanged(int pageSize)
{
        CurrentPageSize = pageSize;
        await LoadDataAsync();
}
    

Sorting, Filtering, and LoadDataAsync is all custom mapped to the API request. Only the LoadData is used to send the requests.

  1. Change the PageSize on the drop down list on the DataGrid.
  2. Notice that a re-render is made before CurrentPageSize is properly updated, and if the page is bound to an api request it should be 1 event behind what the page size was chosen.
  3. If calling the API through the PageSizeChanged you should see two calls 1) with the old/current PageSize and 2) with the correct new PageSize

Expected behavior
LoadData event should be called after the PageSizeChanged event has triggered, allowing a request to be properly set up before triggering a reload of the data.

Desktop (please complete the following information):

  • OS: Windows
  • Browser: Edge
  • Radzen Version: 5.7.1
Originally created by @eirgje on GitHub (Dec 19, 2024). <!-- IMPORTANT: Read this first!!! 1. If you own a Radzen Professional or Еnterprise subscription you can report your issue or ask us a question via email at info@radzen.com. Radzen staff will reply within 24 hours (Professional) or 16 hours (Enterprise) 2. The Radzen staff guarantees a response to issues in this repo only to paid subscribers. 3. If you have a HOW TO question start a new forum thread in the Radzen Community forum: https://forum.radzen.com. Radzen staff will close issues that are HOWTO questions. 4. Please adhere to the issue template. Specify all the steps required to reproduce the issue or link a project which reproduces it easily (without requiring extra steps such as restoring a database). --> **Describe the bug** We are connecting an API with pagination to a RadzenDataGrid, our LoadData mapping trigger a new request to the API. The PageSizeOptions being mapped triggers a secondary LoadData call before all the internal properties can be set and returned to the API request parameters. This requires us to create a mapping to the PageSizeChanged event and trigger a secondary API request. When holding a reference to the RadzenDataGrid through ref we can find the expected value, but the methods and properties we can bind to on the RadzenDataGrid is acting after the LoadData event resulting in the PageSize property mapped being one event behind the actual PageSize selected by the user. **To Reproduce** Steps to reproduce the behavior: 1. Create a RadzenDataGrid 2. Map the following: Attempt 1: ``` <RadzenDataGrid class="w-100 h-100 overflow-hidden" TItem="ApiResponse" Density="Density.Compact" ExpandMode="@DataGridExpandMode.Single" AllowColumnResize="@true" AllowColumnPicking="@true" AllowPaging="@true" PagerAlwaysVisible="@true" PagerHorizontalAlign="@HorizontalAlign.Center" ShowPagingSummary="@true" Page="@PageChanged" @bind-PageSize="@CurrentPageSize" PageSizeOptions="@PageSizeOptions" LoadData="@LoadDataAsync" IsLoading="@IsLoading" GotoFirstPageOnSort="@true" Sort="@(args => Sort(args.SortOrder.ToStringValue(), args.Column.GetSortProperty()))" Data="@Data" AllowSorting="@true" AllowFiltering="@true" PagingSummaryFormat="@.DataGridPagerSummary" PageSizeText="@DataGridPageSizeSummary" ColumnsShowingText="@.DataGridColumnsSummary"> ``` Attempt 2: ``` <RadzenDataGrid class="w-100 h-100 overflow-hidden" TItem="ApiResponse" Density="Density.Compact" ExpandMode="@DataGridExpandMode.Single" AllowColumnResize="@true" AllowColumnPicking="@true" AllowPaging="@true" PagerAlwaysVisible="@true" PagerHorizontalAlign="@HorizontalAlign.Center" ShowPagingSummary="@true" Page="@PageChanged" PageSizeChanged="@PageSizeChanged" PageSize="@CurrentPageSize" PageSizeOptions="@PageSizeOptions" LoadData="@LoadDataAsync" IsLoading="@IsLoading" GotoFirstPageOnSort="@true" Sort="@(args => Sort(args.SortOrder.ToStringValue(), args.Column.GetSortProperty()))" Data="@Data" AllowSorting="@true" AllowFiltering="@true" PagingSummaryFormat="@.DataGridPagerSummary" PageSizeText="@DataGridPageSizeSummary" ColumnsShowingText="@.DataGridColumnsSummary"> private async Task PageSizeChanged(int pageSize) { CurrentPageSize = pageSize; await LoadDataAsync(); } ``` Sorting, Filtering, and LoadDataAsync is all custom mapped to the API request. Only the LoadData is used to send the requests. 3. Change the PageSize on the drop down list on the DataGrid. 4. Notice that a re-render is made before CurrentPageSize is properly updated, and if the page is bound to an api request it should be 1 event behind what the page size was chosen. 5. If calling the API through the PageSizeChanged you should see two calls 1) with the old/current PageSize and 2) with the correct new PageSize **Expected behavior** LoadData event should be called after the PageSizeChanged event has triggered, allowing a request to be properly set up before triggering a reload of the data. **Desktop (please complete the following information):** - OS: Windows - Browser: Edge - Radzen Version: 5.7.1
Author
Owner

@enchev commented on GitHub (Dec 20, 2024):

I'm afraid that we cannot run the code provided, still I'm not sure why you need PageSizeChanged event at all since LoadData will be called when page size is changed and you have everything needed in LoadData event:

@using System.Linq.Dynamic.Core
@using RadzenBlazorDemos.Data
@using RadzenBlazorDemos.Models.Northwind
@using Microsoft.EntityFrameworkCore

@inherits DbContextPage

<RadzenButton Text="Refresh" Click="@(args => grid.Reload())" class="rz-my-4" />

<RadzenDataGrid @ref=grid Data="@orderDetails" PageSizeOptions="@pageSizeOptions" Count="@count" LoadData="@LoadData" Style="height:400px"
                AllowFiltering="true" FilterPopupRenderMode="PopupRenderMode.OnDemand" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" LogicalFilterOperator="LogicalFilterOperator.Or"
                AllowSorting="true" AllowPaging=true>
    <Columns>
        <RadzenDataGridColumn Property="@nameof(OrderDetail.OrderID)" Title="OrderID" />
        <RadzenDataGridColumn Property="@nameof(OrderDetail.ProductID)" Title="ProductID" />
        <RadzenDataGridColumn Property="@nameof(OrderDetail.UnitPrice)" Title="Unit Price">
            <Template Context="detail">
                @String.Format(new System.Globalization.CultureInfo("en-US"), "{0:C}", detail.UnitPrice)
            </Template>
        </RadzenDataGridColumn>
        <RadzenDataGridColumn Property="@nameof(OrderDetail.Quantity)" Title="Quantity" />
        <RadzenDataGridColumn Property="@nameof(OrderDetail.Discount)" Title="Discount">
            <Template Context="detail">
                @String.Format("{0}%", detail.Discount * 100)
            </Template>
        </RadzenDataGridColumn>
    </Columns>
</RadzenDataGrid>

<EventConsole @ref=@console />
@code {
    IEnumerable<int> pageSizeOptions = new int[] { 10, 20, 30 };
    EventConsole console;
    RadzenDataGrid<OrderDetail> grid;
    int count;
    IEnumerable<OrderDetail> orderDetails;

    string lastfilter;
    async Task LoadData(LoadDataArgs args)
    {
        await Task.Yield();

        if(!string.IsNullOrEmpty(args.Filter) && lastfilter != args.Filter)
        {
            args.Skip = 0;
        }

        console.Log($"Skip: {args.Skip}, Top: {args.Top}");

        var query = dbContext.OrderDetails.AsQueryable();

        if (!string.IsNullOrEmpty(args.Filter))
        {
            lastfilter = args.Filter;
            query = query.Where(args.Filter);
            count = await Task.FromResult(query.Count());
        }
        else
        {
            count = await Task.FromResult(dbContext.OrderDetails.Count());
        }

        if (!string.IsNullOrEmpty(args.OrderBy))
        {
            query = query.OrderBy(args.OrderBy);
        }

        orderDetails = await Task.FromResult(query.Skip(args.Skip.Value).Take(args.Top.Value).ToList());
    }
}

image

@enchev commented on GitHub (Dec 20, 2024): I'm afraid that we cannot run the code provided, still I'm not sure why you need PageSizeChanged event at all since LoadData will be called when page size is changed and you have everything needed in LoadData event: ``` @using System.Linq.Dynamic.Core @using RadzenBlazorDemos.Data @using RadzenBlazorDemos.Models.Northwind @using Microsoft.EntityFrameworkCore @inherits DbContextPage <RadzenButton Text="Refresh" Click="@(args => grid.Reload())" class="rz-my-4" /> <RadzenDataGrid @ref=grid Data="@orderDetails" PageSizeOptions="@pageSizeOptions" Count="@count" LoadData="@LoadData" Style="height:400px" AllowFiltering="true" FilterPopupRenderMode="PopupRenderMode.OnDemand" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" LogicalFilterOperator="LogicalFilterOperator.Or" AllowSorting="true" AllowPaging=true> <Columns> <RadzenDataGridColumn Property="@nameof(OrderDetail.OrderID)" Title="OrderID" /> <RadzenDataGridColumn Property="@nameof(OrderDetail.ProductID)" Title="ProductID" /> <RadzenDataGridColumn Property="@nameof(OrderDetail.UnitPrice)" Title="Unit Price"> <Template Context="detail"> @String.Format(new System.Globalization.CultureInfo("en-US"), "{0:C}", detail.UnitPrice) </Template> </RadzenDataGridColumn> <RadzenDataGridColumn Property="@nameof(OrderDetail.Quantity)" Title="Quantity" /> <RadzenDataGridColumn Property="@nameof(OrderDetail.Discount)" Title="Discount"> <Template Context="detail"> @String.Format("{0}%", detail.Discount * 100) </Template> </RadzenDataGridColumn> </Columns> </RadzenDataGrid> <EventConsole @ref=@console /> @code { IEnumerable<int> pageSizeOptions = new int[] { 10, 20, 30 }; EventConsole console; RadzenDataGrid<OrderDetail> grid; int count; IEnumerable<OrderDetail> orderDetails; string lastfilter; async Task LoadData(LoadDataArgs args) { await Task.Yield(); if(!string.IsNullOrEmpty(args.Filter) && lastfilter != args.Filter) { args.Skip = 0; } console.Log($"Skip: {args.Skip}, Top: {args.Top}"); var query = dbContext.OrderDetails.AsQueryable(); if (!string.IsNullOrEmpty(args.Filter)) { lastfilter = args.Filter; query = query.Where(args.Filter); count = await Task.FromResult(query.Count()); } else { count = await Task.FromResult(dbContext.OrderDetails.Count()); } if (!string.IsNullOrEmpty(args.OrderBy)) { query = query.OrderBy(args.OrderBy); } orderDetails = await Task.FromResult(query.Skip(args.Skip.Value).Take(args.Top.Value).ToList()); } } ``` ![image](https://github.com/user-attachments/assets/e839da6e-ebc0-4d51-b3e4-b4018d8d28bf)
Author
Owner

@eirgje commented on GitHub (Dec 20, 2024):

Thank you so much for your response, we are absolute idiots for not noticing the param in this method. Thank you so much for taking the time to respond.

@eirgje commented on GitHub (Dec 20, 2024): Thank you so much for your response, we are absolute idiots for not noticing the param in this method. Thank you so much for taking the time to respond.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/radzen-blazor#1541