MatSelectValue: null reference exception when setting Items async
TrevorDArcyEvans opened this issue · comments
Trevor D'Arcy-Evans commented
Describe the bug
Not sure what I'm doing wrong but trying to load Items for a MatSelectValue async from a database and getting NRE (null reference exception)
To Reproduce
Sample code:
@page "/"
<h1>Hello, MatBlazor world!</h1>
<MatSelectValue @bind-Value="_value3" Items="@_value3Items" ValueSelector="@(i => i)">
<ItemTemplate>
<span style="color: @context.Color">@context?.Name</span>
</ItemTemplate>
</MatSelectValue>
<p>
Selected value: @_value3?.Name
</p>
@code
{
private ItemType _value3;
private ItemType[] _value3Items;
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
_value3Items = await GetData();
}
private async Task<ItemType[]> GetData()
{
await Task.Delay(TimeSpan.FromSeconds(0.5));
var retval = new[]
{
new ItemType("", "black"),
new ItemType("Grains", "brown"),
new ItemType("Vegetables", "green"),
new ItemType("Fruit", "orange"),
};
return retval;
}
private class ItemType
{
public string Name { get; }
public string Color { get; }
public ItemType(string name, string color)
{
Name = name;
Color = color;
}
}
}
Note that delay is to simulate latency calling a database.
Expected behavior
MatSelectValue should update Items successfully
Callstack
Content root path: C:\dev\trevorde\MatBlazorTest
warn: Microsoft.AspNetCore.Components.Server.Circuits.RemoteRenderer[100]
Unhandled exception rendering component: Value cannot be null. (Parameter 'items')
System.ArgumentNullException: Value cannot be null. (Parameter 'items')
at MatBlazor.LinqExtensions.FindIndex[T](IEnumerable`1 items, Func`2 predicate) in C:\dev\trevorde\MatBlazor\src\MatBlazor\Core\LinqExtensions.cs:line 16
at MatBlazor.BaseMatSelectValue`2.GetKeyFromValue(TValue value) in C:\dev\trevorde\MatBlazor\src\MatBlazor\Components\MatSelect\BaseMatSelectValue.cs:line 16
at MatBlazor.BaseCoreMatSelect`2.<.ctor>b__3_7() in C:\dev\trevorde\MatBlazor\src\MatBlazor\Components\MatSelect\BaseCoreMatSelect.cs:line 43
at MatBlazor.BaseMatComponent.OnAfterRenderAsync(Boolean firstRender) in C:\dev\trevorde\MatBlazor\src\MatBlazor\Components\Base\BaseMatComponent.cs:line 46
fail: Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost[111]
Unhandled exception in circuit 'HIiiD-zcFM7iwRS-AdKvVYf2b_WtBs0VfN_6J4PppCU'.
System.AggregateException: One or more errors occurred. (Value cannot be null. (Parameter 'items'))
---> System.ArgumentNullException: Value cannot be null. (Parameter 'items')
at MatBlazor.LinqExtensions.FindIndex[T](IEnumerable`1 items, Func`2 predicate) in C:\dev\trevorde\MatBlazor\src\MatBlazor\Core\LinqExtensions.cs:line 16
at MatBlazor.BaseMatSelectValue`2.GetKeyFromValue(TValue value) in C:\dev\trevorde\MatBlazor\src\MatBlazor\Components\MatSelect\BaseMatSelectValue.cs:line 16
at MatBlazor.BaseCoreMatSelect`2.<.ctor>b__3_7() in C:\dev\trevorde\MatBlazor\src\MatBlazor\Components\MatSelect\BaseCoreMatSelect.cs:line 43
at MatBlazor.BaseMatComponent.OnAfterRenderAsync(Boolean firstRender) in C:\dev\trevorde\MatBlazor\src\MatBlazor\Components\Base\BaseMatComponent.cs:line 46
--- End of inner exception stack trace ---
Md Tomal Hossain commented
Anyone facing this issue, you can do two things to avoid this kind of error:
- Put an
if
condition outside the component:
@if(_value3Items != null) {
<MatSelectValue @bind-Value="_value3" Items="@_value3Items" ValueSelector="@(i => i)">
<ItemTemplate>
<span style="color: @context.Color">@context?.Name</span>
</ItemTemplate>
</MatSelectValue>
}
- initialize the items with an empty array or list.
private ItemType[] _value3Items = new ItemType[] {};
Reason: When it's trying to render the select component, it operates a loop through it's Items
and it can perform on a null
value.