SamProf / MatBlazor

Material Design components for Blazor and Razor Components

Home Page:http://www.matblazor.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

MatSelectValue: null reference exception when setting Items async

TrevorDArcyEvans opened this issue · comments

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 ---

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.