Hello,
I'm using property query with SfDataManager on TreeGrid,
The first time, TreeGrid displays all data and 1 seconde after, is refreshed with query data, for second time and after, razor page is blocked, traces give us informations (below)
Moreover data are expanded whereas property ExpandStateMapping="false"
It's works good for all when i use data from datasource property
TreeGrid :
<SfTreeGrid TValue=TraceabilityResult @ref="_traceabilityResultListGrid" Toolbar="_toolbar" AllowSorting="true" AllowFiltering="true" AllowPaging="true" AllowResizing="true"
AllowSelection="false" EnableHover="false" AllowExcelExport="true" AllowPdfExport="true" Height="100%" Width="100%"
IdMapping="@nameof(TraceabilityResult.Id)" ParentIdMapping="@nameof(TraceabilityResult.ParentId)" TreeColumnIndex="0" ExpandStateMapping="false"
HasChildMapping="@nameof(TraceabilityResult.IsParent)" LoadChildOnDemand="true" Query="@_trQuery">
<SfDataManager Url="TraceabilityResults" Adaptor="Adaptors.ODataV4Adaptor" CrossDomain="true" HttpClientInstance="ApisService.CoreHttpClientOData" />
code
{
private Query? _trQuery { get; set; } = null;
_trQuery = new Query().Where("TrRequestID", "equal", _requestId);
}
Traces :
fail: Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost[111]
Unhandled exception in circuit 'pC9YMAsF1Kaz25jfRfpd8b4019Yh87BPIWuO7RNuAns'.
System.NullReferenceException: Object reference not set to an instance of an object.
at Syncfusion.Blazor.TreeGrid.Internal.Edit`1.ActionBegin(ActionEventArgs`1 args, ActionEventArgs`1 remoteArgs) at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__128_0(Object state)
at Microsoft.AspNetCore.Components.Rendering.RendererSynchronizationContext.ExecuteSynchronously(TaskCompletionSource`1 completion, SendOrPostCallback d, Object state)
at Microsoft.AspNetCore.Components.Rendering.RendererSynchronizationContext.<>c.<.cctor>b__23_0(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at Microsoft.AspNetCore.Components.Rendering.RendererSynchronizationContext.ExecuteBackground(WorkItem item)
warn: Microsoft.AspNetCore.Components.Web.ErrorBoundary[100]
Unhandled exception rendering component: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')
System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')
at Syncfusion.Blazor.TreeGrid.Internal.GridRenderer`1.CreateEventHandler(Object args)
at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
at Syncfusion.Blazor.Grids.SfGrid`1.OnAfterScriptRendered()
at Syncfusion.Blazor.SfBaseComponent.OnAfterRenderAsync(Boolean firstRender)
at Syncfusion.Blazor.SfDataBoundComponent.OnAfterRenderAsync(Boolean firstRender)
at Syncfusion.Blazor.Grids.SfGrid`1.OnAfterRenderAsync(Boolean firstRender)
at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState
Thanks you
Hi Julian,
Greetings from Syncfusion support.
Please find the responses to your queries below:
Query #1: The TreeGrid displays all data initially and after 1 second it refreshes with new data. Subsequently, the razor page is blocked, and the traces provide the following information (see below).
Based on the call stack you provided, we suspect that the issue was caused due to no columns found in treegrid. We must define the columns using TreeGridColumn. We need additional information to check this issue further.
Query #2:
Data appears expanded despite using the property
`ExpandStateMapping="false"`
The behavior of `ExpandStateMapping` property is different. It ensures that each parent record in datasource retain their expanded or collapsed state at initial rendering or refresh. This property corresponds to a value within the data object of the data source, signifying the expand/collapse status of the parent row.
Code
snippet:
|
<SfTreeGrid TValue="TaskData" AllowSorting="true" AllowFiltering="true" AllowPaging="true" AllowResizing="true" AllowSelection="false" EnableHover="false" AllowExcelExport="true" AllowPdfExport="true" Height="100%" Width="100%" IdMapping=" ID" ParentIdMapping="ParentId" ExpandStateMapping="isExpandstate" HasChildMapping="isParent" Query="@GridQuery" Toolbar="@(new List<string>(){ "Add", "Edit", "Update", "Cancel", "Delete"})"> public class TaskData { . . . . public bool? isExpandstate { get; set; } . . . . } |
In
the shared sample, the datasource object has an isExpanded property
with a Boolean value. Based on this value, the parent rows are rendered in an
expanded or collapsed state. Attached the
sample for reference.
Also
we reviewed the code snippet you shared. It seems that you have enabled the
`LoadChildOnDemand` feature, which causes parent records to render in an
expanded state by default.
Note: We introduced a
breaking change in the `LoadChildOnDemand` feature in the Volume 3 2024 main
release (v27.1.48). With this update, parent records are initially rendered in
a collapsed state, and child records are only loaded when the parent row is expanded
when we set the LoadChildOnDemand to true.
Release
Notes: https://blazor.syncfusion.com/documentation/release-notes/27.1.48?type=all#tree-grid
Please let
us know if you need further assistance or clarification.
Regards,
Shek
Hi Shek, thanks for your reply
Query #1: As you can see below i think i defined good the columns in treegrid because it's works pretty well with datasource property. I updated syncfusion in v 27.1.48 and the issue is still appears.
I tried the WepApiAdap.zip and i have also an issue (join both pictures)
I noticed that property onDataBound not working.
<TreeGridEvents TValue="TraceabilityResult" DataBound="InitToolbar" OnActionFailure="GridActionFailureHandler" /> and issue is not detected by OnActionFailure.
Query #2: I was focus on the first one for the moment.
I saw the new property TreeGrid.GetTotalItemsCountAsync() to have the number total, i don't know if it's possible to have the information after query execution.
Thanks
Hi Julian,
Query #1: As you can see below, I think I defined good the columns in treegrid because it's works pretty well with datasource property. I updated syncfusion in v 27.1.48 and the issue still appears.
Sorry for the inconvenience caused.
We can replicate the issue from the shared sample. That is because of the Get method not handled properly for the query from our end. We have created a new sample which handles the query property.
Sample attached with this response.
Quert : I noticed that property onDataBound not working.
We suspect that the DataBound event not triggered on initial rendering. We cannot replicate the issue from our the above sample. The DataBound event triggered properly on the initial load. Kindly share the complete treegrid code snippet to replicate the DataBound not triggered issue and project exception from our end.
Query #2: I saw the new property TreeGrid.GetTotalItemsCountAsync() to have the number total, i don't know if it's possible to have the information after query execution.
We can get the number of TotalItemsCount of the dataSource in DataBound event once the data bound in treegrid.
Code-snippet:
|
public void DataBound() { var totalRecords = tree.GetTotalItemsCountAsync(); } |
Note: The abode methos will display the number of records at the view port.
Kindly get back to us for further assistance.
Regards,
Shek
Hi Shek,
I changed the query because i always have every row of Tasks table and this is not the subject of my request. I want to filter on data with Query and datamanager property.
i join you the same example with issue :
For example, I want to display rows in TreeGrid for Duration=12. But I can't modify the Tasks table data (TaskID : 79878 must have Duration=12 too) to display Task ID 1 / 2 / 5 and 10 when it's collapse, ok ?
You can launch app and then go to datagrid feature page and go back to TreeGrid page and see the issue.
Thanks
Hi Julian,
To filter the duration on initial rendering, we need to customize the dataSource based on the filter value in server. We have customized the server and modified the sample. Please refer to the following code snippets.
|
public object Get() { var queryString = Request.Query; IQueryable<TreeGridWebApiEFSample.Shared.Models.Task> data1 = db.GetAllRecords().AsQueryable(); . . . . .
if (queryString.Keys.Contains("$filter") && queryString.Keys.Count > 2) { StringValues filter; var filteredRecords = data1; queryString.TryGetValue("$filter", out filter);
if (!filter.ToList()[0].Contains("null")) { // Extract the filter property and value var fltr = filter[0].ToString().Split("eq")[1].Trim(); // Filter value (e.g., "12" or "13") var prop = filter[0].ToString().Split("eq")[0].Trim(); // Property name (e.g., "Duration")
// Check if the property exists in the model if (data1.ToList()[0].GetType().GetProperty(prop)?.Name != null) { // Apply filtering on both parent and child records filteredRecords = data1.Where(data => data.GetType().GetProperty(prop).GetValue(data, null) != null && data.GetType().GetProperty(prop).GetValue(data, null).ToString().Contains(fltr)).AsQueryable(); }
// Find the IDs of the parents whose children matched the filter var filteredParentIds = filteredRecords.Where(x => x.ParentID != null) .Select(x => x.ParentID) .Distinct() .ToList(); // ParentIDs of children that match the filter
// Include parent records if they matched the filter, and also those whose children matched the filter var parentsWithMatchingChildren = data1.Where(data => filteredParentIds.Contains(data.TaskID)).ToList();
// Filter to show only the children that match or all children of matching parents var childRecords = filteredRecords.Where(x => x.ParentID != null).ToList(); var allFilteredRecords = parentsWithMatchingChildren .Union(filteredRecords.Where(x => x.ParentID == null)) // Include matching parents .Union(childRecords) // Include only matching children or all children for matched parents .Distinct() .ToList();
// Now filter to keep only the relevant children (those whose parents matched or they themselves matched) var parentIdsWithMatchingChildren = allFilteredRecords.Where(p => p.ParentID == null) .Select(p => p.TaskID) .ToList();
// Update child records: Keep only children whose parent matches the filter or themselves match the filter var matchingChildRecords = allFilteredRecords.Where(x => parentIdsWithMatchingChildren.Contains(x.ParentID ?? 0) || x.ParentID == null).ToList();
// COLLAPSING LOGIC: Show only the parent records (ParentID == null) var parentRecords = matchingChildRecords.Where(data => data.ParentID == null).AsQueryable();
// Optionally, maintain the hierarchy for expansion var hierarchy = parentRecords.Select(parent => new { Parent = parent, Children = matchingChildRecords.Where(child => child.ParentID == parent.TaskID).ToList() // Find the children of each parent }).ToList();
return new { Items = parentRecords, // Or return hierarchy if you want to include the full hierarchy structure Count = parentRecords.Count() // Count of top-level records (collapsed view) }; } } . . . . . } |
We have encountered an issue when expanding a record in the tree grid. It appears that the entire child set binds to the expanding parent due to the filter value being set to the expanding record. Currently, the filter value that we pass during the initial rendering using the query is not retained when expanding a row. This causes unintended behavior where the filtered child records are not correctly displayed.
We have considered the above issue (“Unable to get query value on expanding”) as a bug. Thank you for taking the time to report this issue and helping us improve our product. At Syncfusion, we are committed to fixing all validated defects (subject to technological feasibility and Product Development Life Cycle) and will include the fix in our upcoming NuGet release which is expected to be rolled out on November 05, 2024. Until then we appreciate your patience.
You can now track the status of your request, review the proposed resolution timeline, and contact us for any further inquiries through this link.
https://www.syncfusion.com/feedback/62347/unable-to-get-query-value-on-expanding
Note: To view the above feedback, kindly login into your account.
Disclaimer: Inclusion of this solution in the weekly release may change due to other factors including but not limited to QA checks and works reprioritization.
Regards,
Shek
Hi Shek,
i updated the last syncfusion version for issue "Unable to get query value on expanding"
It's better but not perfect (on example and project)
So, i send you the example with modifications for DataBound and Filtered issue
I joined on the zip a word file Issues.docs with screenshoots and code project
Thanks
Hi Julian,
With the latest patch release, we recommend including the expanding key in the query along with the initial query to fetch the child records based on the parent ID of the expanded node. To implement this, please refer to the following code snippet:
|
[HttpGet] public object Get() { var queryString = Request.Query; IQueryable<TreeGridWebApiEFSample.Shared.Models.Task> data1 = db.GetAllRecords().AsQueryable();
IQueryable<TreeGridWebApiEFSample.Shared.Models.Task> data2; if (queryString.Keys.Contains("$filter") && !queryString.Keys.Contains("$top")) { if (queryString.TryGetValue("$filter", out StringValues filter) && filter.Count > 0) { var filterParts = filter[0].Split("and");
if (filterParts.Length >= 2) { // Extract and parse the filter values with trimming and safe parsing var fltrString = filterParts[0].Split("eq")[1].Trim(); var fltr2String = filterParts[1].Split("eq")[1].Trim();
if (int.TryParse(fltrString, out int fltr) && int.TryParse(fltr2String, out int fltr2)) { // Apply the filters in the LINQ query data2 = data1.Where(f => f.Duration == fltr && f.ParentID == fltr2).AsQueryable();
return new { Items = data2, Count = data2.Count() }; } } }
// Return an empty result if parsing fails return new { Items = Enumerable.Empty<object>().AsQueryable(), Count = 0 }; } |
We have attached sample for your reference. If you have any doubts, kindly get back to us.
Regards,
Shek