Declined
Last Updated: 22 Sep 2020 15:04 by ADMIN
Steven
Created on: 21 Sep 2020 17:48
Category: UI for Blazor
Type: Bug Report
0
Grid Footer Template causes filtering to crash when the input you type does not exist in any row in the grid.

In a Telerik Grid, we had just implemented the new Grid Footer Template.  However, any built-in filtering (filterrow, filtermenu, searchbox) we use now will cause the grid/page to crash when the input we type does not exist for any row in the grid.  If the input we type does exist, the filtering works correctly.  For instance, if wanted to filter the name "John Smith" and a row exists with that name, then that row will be filtered.  If we typed in "John Smithasdf", then the grid crashes and we receive the following message from the DevTools window:

blazor.server.js:19 [2020-09-21T16:58:12.070Z] Error: System.InvalidOperationException: Nullable object must have a value.
   at System.Nullable`1.get_Value()
   at BudgetPak.Pages.User.Budgeting.HeadcountReview.<>c__DisplayClass0_4.<BuildRenderTree>b__43(RenderTreeBuilder __builder4)
   at Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder.AddContent(Int32 sequence, RenderFragment fragment)
at Telerik.Blazor.Components.Grid.GridFooterCell`1.BuildRenderTree(RenderTreeBuilder __builder)
   at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.RenderInExistingBatch(RenderQueueEntry renderQueueEntry)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue()

From the highlighted text, we deduced the issue had to deal with the Grid Footer template.  Not all of our columns are aggregated on the footer row, so we were thinking that's what the "Nullable object must have a value" message meant.  When we removed the Grid Footer template, the filtering worked correctly.  With one of our other grids, we added a temporary footer grid, and the same crash would occur.

Is there a work-around for this?  The footer template otherwise is great, and we would like to use both that and filtering on our grids.  Please let us know if you need any more info.

Thanks,

Steve

3 comments
ADMIN
Marin Bratanov
Posted on: 22 Sep 2020 15:04

Thank you for getting back to me, Steve.

I am marking this as "declined" since it was not a bug in the component, but an oversight in the documentation on my part. Thank you again for bringing it up.

 

Regards,
Marin Bratanov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Steven
Posted on: 22 Sep 2020 14:54

Hi Marin,

Yes, that worked.  Thank you so much!  I think what threw me off was that our null values were being formatted to 0's on the grid.  It gave me the impression that the reason for the error was caused by columns that were not being aggregated, and its footer values were therefore blank/null.

Thanks again!

Steve

ADMIN
Marin Bratanov
Posted on: 22 Sep 2020 06:56

Hello Steve,

Thank you for bringing this up. The issue is that when filtering returns no items, there can be no aggregation, and so a null check is needed before using those aggregates. I hadn't thought of that when writing the docs, and so I updated the article to have examples of this.

Here's the sample code as well - I cannot make it throw an exception. Am I missing something? The changes are highglighted.

Could you confirm if this approach works for you? If you still get errors, can you modify this sample to showcase the issue so I can have a peek and see if it's an issue in the snippet or in the component?

 

<TelerikGrid Data=@GridData Pageable="true" Height="500px" Sortable="true" Groupable="true" FilterMode="@GridFilterMode.FilterRow">
    <GridAggregates>
        <GridAggregate Field=@nameof(Employee.Salary) Aggregate="@GridAggregateType.Max" />
        <GridAggregate Field=@nameof(Employee.Salary) Aggregate="@GridAggregateType.Sum" />
        <GridAggregate Field=@nameof(Employee.EmployeeId) Aggregate="@GridAggregateType.Count" />
    </GridAggregates>
    <GridColumns>
        <GridColumn Field="@nameof(Employee.EmployeeId)"></GridColumn>
        <GridColumn Field=@nameof(Employee.Salary) Title="Salary">
            <FooterTemplate>
                Total salaries: @context.Sum?.ToString("C0")
                <br />
                Highest salary: @context.Max?.ToString("C0")
            </FooterTemplate>
        </GridColumn>
        <GridColumn Field=@nameof(Employee.Name)>
            <FooterTemplate>
                @{
                    // you can use aggregates for other fields/columns by extracting the desired one by its
                    // field name and aggregate function from the AggregateResults collection
                    // The type of its Value is determined by the type of its field - decimal for the Salary field here
                    int? headCount = (int?)context?.AggregateResults
                        .FirstOrDefault(r => r.AggregateMethodName == "Count" && r.Member == nameof(Employee.EmployeeId))?.Value;
                }
                Total employees: @headCount
            </FooterTemplate>
        </GridColumn>
    </GridColumns>
    <GridToolBar>
        <GridSearchBox />
    </GridToolBar>
</TelerikGrid>

@code {
    public List<Employee> GridData { get; set; }

    protected override void OnInitialized()
    {
        GridData = new List<Employee>();
        var rand = new Random();
        for (int i = 0; i < 15; i++)
        {
            Random rnd = new Random();
            GridData.Add(new Employee()
            {
                EmployeeId = i,
                Name = "Employee " + i.ToString(),
                Salary = rnd.Next(1000, 5000),
            });
        }
    }

    public class Employee
    {
        public int EmployeeId { get; set; }
        public string Name { get; set; }
        public decimal Salary { get; set; }
    }
}

 

 

 

Regards,
Marin Bratanov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.