Hi There,
I am using a querybuilder component in my project, and while creating rules from scratch in the component works fine, setting rules through any method throws the following exception:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Cannot implicitly convert type 'System.Text.Json.JsonElement' to 'string'
at CallSite.Target(Closure , CallSite , Object )
at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
at Syncfusion.Blazor.QueryBuilder.Internal.QueryBuilderRules`1.SetField()
at Syncfusion.Blazor.QueryBuilder.Internal.QueryBuilderRules`1.OnParametersSetAsync()
at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost: Error: Unhandled exception in circuit '8OzBvqX9F2DatOGOCDy0mQ9H43g3qH4cxECT6t7oEy8'.
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Cannot implicitly convert type 'System.Text.Json.JsonElement' to 'string'
at CallSite.Target(Closure , CallSite , Object )
at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
at Syncfusion.Blazor.QueryBuilder.Internal.QueryBuilderRules`1.SetField()
at Syncfusion.Blazor.QueryBuilder.Internal.QueryBuilderRules`1.OnParametersSetAsync()
at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
I have tried:
<SfQueryBuilder TValue="ExpandoObject" MaxGroupCount="0" @ref="queryBuilder">
<QueryBuilderRule Condition="and" Rules="@rules"></QueryBuilderRule>
(ExpandoObject type is being used as columns are created dynamicly in a foreach loop)
2. Setting rules after render with the "AddRule" method:
foreach (var rule in entityFilterView.entityFilterOptions.FilterRules)
{
queryBuilder.AddRule(rule,"0");
}
//This foreach loop is an object of type List<RuleModel>
It seems that there is an internal error in the component with json deserialization. Your documentation is also very vague on how to import rules pre and post init without hardco
<SfQueryBuilder TValue="ExpandoObject" @ref="QuerybuilderObj">
<QueryBuilderColumns>
@{
foreach(var column in columns)
{
<QueryBuilderColumn Field="@column.Field" Label="@column.Label" Type="@column.Type" Operators="@column.Operators"></QueryBuilderColumn>
}
}
</QueryBuilderColumns>
</SfQueryBuilder>
<SfButton @onclick="addRule" IsPrimary="true" Content="Add Rules"></SfButton>
@code {
SfQueryBuilder<ExpandoObject> QuerybuilderObj;
RuleModel SampRule = new RuleModel()
{
Label = "Employee ID",
Field = "EmployeeID",
Type = "Number",
Operator = "equal",
Value = 1091
};
private List<QueryBuilderColumn> columns = new();
private static string[] Values = new string[] { "Mr.", "Mrs." };
public List<OperatorsModel> CustomOperators = new List<OperatorsModel> {
new OperatorsModel { Text="Equal", Value="equal"},
new OperatorsModel { Text="Not equal", Value="notequal"}
};
protected override async Task OnInitializedAsync()
{
columns = new List<QueryBuilderColumn>()
{
new QueryBuilderColumn(){ Field="EmployeeID", Label="Employee ID", Type=ColumnType.Number, Operators=CustomOperators},
new QueryBuilderColumn(){ Field="FirstName", Label="First Name", Type=ColumnType.String, Operators=CustomOperators},
new QueryBuilderColumn(){ Field="TitleOfCourtesy", Label="Title of Courtesy", Type=ColumnType.Boolean, Values=Values },
};
await base.OnInitializedAsync();
}
private void addRule()
{
QuerybuilderObj.AddRule(SampRule, "0");
}
} |
Hi Gayathri,
The flow of my page/ component is:
OnAfterRenderAsync : (This is done in the OnAfterRenderAsync Task to not stall the UI of the user on initialization as there is a webapi being called)
The user cannot click a button to retrieve their rules from the database. This is an "edit query" page that edits queries persisted to a database.
The main problem here is that it seems that this cannot be done in a loading "flow"... I have attached a mock up project that simulates the same behaviour and the rules not being populated.
@if (Columns != null)
{
<SfQueryBuilder TValue="string[]" MaxGroupCount="0" @ref="queryBuilderobj">
<QueryBuilderRule Rules="ruleModels" Condition="and"></QueryBuilderRule>
<QueryBuilderColumns>
@foreach (var col in Columns)
{
<QueryBuilderColumn Field="@col.Field" Label="@col.Label" Type="@col.Type" Operators="@cOperators"></QueryBuilderColumn>
}
</QueryBuilderColumns>
</SfQueryBuilder>
}
<div>Test Param: @TestParam</div>
@code{
[Parameter] public string TestParam { get; set; }
SfQueryBuilder<string[]> queryBuilderobj;
private List<QueryBuilderColumn> Columns { get; set; }
List<RuleModel> ruleModels = new();
public List<OperatorsModel> cOperators = new List<OperatorsModel> {
new OperatorsModel { Text="Equal", Value="equal"},
new OperatorsModel { Text="Not equal", Value="notequal"}
};
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
//At this point webapi will be called that returns a a List<RuleModel> object and the columns that is supported.
//The below simulates that webapi call.
Columns = new() {
new QueryBuilderColumn { Field = "Name", Label = "Name", Operators = cOperators, Type = ColumnType.String },
new QueryBuilderColumn { Field = "Email", Label = "Email", Operators = cOperators, Type = ColumnType.String }
};
StateHasChanged();
var rule = new RuleModel();
rule.Field = "Name";
rule.Label = "Name";
rule.Type = "String";
rule.Operator = "equal";
rule.Value = "test 123";
ruleModels.Add(rule);
var rule2 = new RuleModel();
rule2.Field = "Email";
rule2.Label = "Email";
rule2.Type = "String";
rule2.Operator = "notequal";
ruleModels.Add(rule2);
var rule3 = new RuleModel();
rule3.Field = "Name";
rule3.Label = "Name";
rule3.Type = "String";
rule3.Operator = "equal";
rule3.Value = "test_123";
ruleModels.Add(rule3);
StateHasChanged();
}
}
} |