user2382627
user2382627

Reputation:

InputSelect with null reference in Blazor

I'm using an InputSelect in my razor component, but in the console I always see this error:

System.NullReferenceException: Object reference not set to an instance of an object. at VidaConfortoApplication.Client.Pages.ServiceTypes.Add.b__0_7(RenderTreeBuilder __builder3) in C:\repos\sources\VidaConfortoTese\src\VidaConfortoApplication\VidaConfortoApplication\Client\Pages\ServiceTypes\Add.razor:line 18 at Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder.AddContent(Int32 sequence, RenderFragment fragment) at Microsoft.AspNetCore.Components.Forms.InputSelect`1[[System.Int64, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].BuildRenderTree(RenderTreeBuilder builder) at Microsoft.AspNetCore.Components.ComponentBase.<.ctor>b__6_0(RenderTreeBuilder builder) at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment, Exception& renderFragmentException)

I do not understand what I am doing wrong.

Component:

<EditForm Model="@_model"  OnValidSubmit="OnValidSubmit">
    <DataAnnotationsValidator />
    <div class="form-row">

        <div class="form-group col">
            <label>Serviço pai</label>

            <InputSelect class="form-control" @bind-Value="@_model.ParentId">
                <option value="">--</option>
                @foreach (var service in _services)
                {
                    <option value="@service.Id">@service.Name</option>
                }
            </InputSelect>
            <label>@_serviceHierarchy</label>
            <ValidationMessage For="@(() => _model.ParentId)"/>
        </div>
    </div>
    <br />
    <div class="form-group">
        <button class="btn btn-primary">
            Save
        </button>
    </div>
</EditForm>

@code {
    private readonly AddServiceTypeViewModel _model = new();
    private IEnumerable<ServiceType> _services;

    protected override async Task OnInitializedAsync()
    {
        _services = await ServiceTypeService.GetAll();
    }
}

Class AddServiceTypeViewModel

public class AddServiceTypeViewModel
{
    [Required]
    public string Name { get; set; }
    public long? ParentId { get; set; }
    public string? Description { get; set; }
}

Class ServiceType

public class ServiceType
{
    public string Name { get; set; }
    public long? ParentId { get; set; }
    public ServiceType? Parent { get; set; }
    public string? PathToService { get; set; }
    public string? Description { get; set; }
    public DateTime? AddedWhen { get; set; }
    public DateTime? UpdatedWhen { get; set; }
    public long Id { get; set; }
}

Upvotes: 1

Views: 840

Answers (1)

Vi100
Vi100

Reputation: 4203

Your template is trying to access the "_services" property to render some piece of html before it's initialized. To avoid this,

  1. You can initialize it to an empty list:

    private IEnumerable<ServiceType> _services = new List<ServiceType>();
    

or

  1. You can put a guard on the template code:

    if (_services is not null)
    {
        @foreach (var service in _services)
        {
            <option value="@service.Id">@service.Name</option>
        }
    }
    

Upvotes: 2

Related Questions