Lets start with a sample Razor component that renders the UI:
Component.razor
Forename
Surname
Username
@foreach (var user in Users)
{
@user.Forename
@user.Surname
@user.Username
}
Lets look at the ‘code behind’ (ooof I’m old) AKA a partial class that represents the logic of the component (view)
Component.razor.cs
public partial class Component
{
private string _url = String.Empty;
IEnumerable Users { get; set; }
//The Configuration object needs to be injected via dependency injection
protected async override void OnInitializedAsync()
{
_url = Configuration.AllClientSettings().BaseServiceURI;
Users = (await http.CreateClient("ClientSettings").GetFromJsonAsync>($"{_URL}/api/lookup/User"))
.OrderBy(t => t.Username)
.ToList();
}
Looks pretty normal right?
The main issue is the way the method OnInitializedAsync() executes in Blazor. It actually executes TWICE, sort of confusing but there is a good reason!
A few things are going on here:
- Component.razor is initially rendered statically as part of the page, whilst async methods execute in the background.
- Now we’re awaiting the Users IEnumerable<UserModel>, this data may not be accessible on the initial page render since it’s a task that needs to be awaited.
- Once the browser has rendered the component the OnInitializedAsync() method is executed again.
Guess what happens when you try to enumerate an IEnumerable on the first render? It’s null (possibly) due to the nature of asynchronous programming, hence the error!
How to fix this behavior?
The solution is pretty simple, wait for the IEnumerable to be available.
@if(Users is not null)
{
foreach (var user in Users)
{
@user.Forename
@user.Surname
@user.Username
}
}
else
{
Hold tight... loading.
}
What's the good reason for this?
The reason for the OnInitalizedAsync() method executing twice is to allow developers to insert a loading message or load certain static assets before all the razor components are rendered, especially if they’re populated via asynchronous methods. This way the user knows something is happening and they’re waiting for the data/page to load.
Read more here
Hope this helps, I've fallen victim to this myself!
Want to learn more?
Service Collections with Blazor Server
What is a service collection? Service collections are a way of registering and resolving dependencies in C# applications using the built-in dependency injection (DI) system. Blazor Server is a web framework that allows you to…
Read moreIn Memory State Management with Blazor Server
Creating your first In Memory State Container with Blazor Server Web technology has come along way in the relatively recent past. With the surge in popularity of SPAs and Javascript Frameworks a lot of developers…
Read moreWhy Is IHttpContextAccessor/HttpContext null on Blazor Server? Here’s how to fix it!
Table of Contents Why is IHttpContextAccessor -or- HttpContext sometimes null on Blazor Server? The IHttpContextAccessor on Blazor Server is only available on the first Http request when loading a Blazor Server application. After that, all…
Read more