Reputation: 263
I understand the idea of OnAfterRenderAsyc()
but I don't understand how to implement what I want. I have OnInitializedAsync()
that basically gets a summary information from files. After that I want to call 2 other methods and based on information returned from those 2 methods, I want to add some HTML into my component. So far, I have this:
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
driveFiles = await DriveService.GetList(true);
permissionFiles = await DriveService.GetPermissions();
}
await base.OnAfterRenderAsync(firstRender);
}
I then just want to add some basic HTML after OnAfterRenderAsync()
has happened, something like this:
@foreach (var file in driveFiles.Select((value, index) => new {value, index}))
{
<p>
Name: @file.value.FileName
<br />
File Id: @file.value.FileId
<br />
File Number: @file.index
</p>
<hr />
}
How do I do that? I can't find anything on Google that explains how to actually use OnAfterRenderAsync()
, they just explain the basic ideas behind it. I'm sure I am overthinking it, but I can't figure it out
Upvotes: 2
Views: 3725
Reputation: 11392
When invoking asynchronous methods in OnInitializedAsync
the UI will be rendered twice. Once when the first await
is encountered and again when OnInitializedAsync
completes. This enables the component to render mark-up for the user to see whilst it performs background tasks such as retrieving data from a server.
You can also see this behaviour in the following chart of the lifecycle of a blazor component (from microsoft documentation).
During the first render if you try to display your data you will get a null reference exception because the asynchronous task has not completed yet.
The solution is to wrap your ui code inside an if statement:
@if (driveFiles != null)
{
@foreach (var file in driveFiles.Select((value, index) => new {value, index}))
{
<p>
Name: @file.value.FileName
<br />
File Id: @file.value.FileId
<br />
File Number: @file.index
</p>
<hr />
}
}
else
{
@* Show a loading indicator *@
<p>Loading...</p>
}
For your scenario you actually don't need to use OnAfterRenderAsync
method.
Sources:
Upvotes: 7