I tried everything, Googled a lot, still can't get it to work. I'm trying to use <EditForm>
with <InputSelect>
to update an existing object(video
in my case).
I want an
InputSelect
with@bind-Value="video.DisplayId"
. Then the first selected option will be; either 1.if video.DisplayId is null
, then display"None"
. 2.if video.DisplayId is not null
, display the object's name (video.Display.Name
).Then load the whole list of
displays
into options withforeach
, except the currently selected.If
video.DisplayId is not null
then add an option at the end for"None"
.
When loading the Blazor page, everything looks fine with its values, and when I select i.e. from video.Display.Name
to "None"
, and hit Save, it works.
But as soon as I go from "None"
to a display.Name
, it says Object reference not set to an instance of an object (see my code below, where it's saying it).
My code:
<InputSelect @bind-Value="video.DisplayId">
@if (video.DisplayId is null)
{
<option selected value="">None</option>
}
else
{
// Object reference not set to an instance of an object ....
<option selected value="@video.DisplayId">@video.Display.Name</option>
}
@foreach (Display display in displays.Where(display => display.Id != video.DisplayId))
{
<option value="@display.Id">@display.Name</option>
}
@if (video.DisplayId is not null)
{
<option value="">None</option>
}
</InputSelect>
I think it has something to do with Blazor and how it's rendering the page after I select, but how do I fix this issue?
CodePudding user response:
@page "/"
<EditForm Model=@video>
<InputSelect @[email protected]>
@if (video.DisplayId is null)
{
<option value="">none</option>
}
else
{
<option value=@selectedDisplay?.Id>@selectedDisplay?.Name</option>
}
@foreach (var display in unSelectedDisplays)
{
<option [email protected]>@display.Name</option>
}
@if (video.DisplayId is not null)
{
<option value="">none</option>
}
</InputSelect>
</EditForm>
@code {
private Video video = new Video();
private IEnumerable<Display> displays = Enumerable.Empty<Display>();
private IEnumerable<Display> unSelectedDisplays =>
displays.Where(display => display.Id != video.DisplayId);
Display? selectedDisplay => video.DisplayId.HasValue ?
displays.First(d => d.Id == this.video.DisplayId) :
default(Display);
protected override void OnInitialized()
{
displays = Enumerable.Range(0, 10)
.Select(i => new Display { Id = i, Name = $"Name{i}" });
}
public class Display
{
public int Id { get; set; }
public string? Name { get; set; }
}
public class Video
{
public int? DisplayId { get; set; }
}
}
CodePudding user response:
After many more hours, I figured it out. I needed to rewrite the code to following:
<InputSelect @bind-Value="video.DisplayId">
@if (video.DisplayId is null)
{
<option selected value="">None</option>
}
@foreach (Display display in displays)
{
<option value="@display.Id">@display.Name (ID: @display.Id)</option>
}
@if (video.DisplayId is not null)
{
<option value="">None</option>
}
</InputSelect>
And after pressing Save, it calls my method, and inside my method it's changing the data inside the database, and then after that I had to Get the list again from the database.