In Blazor how to call a function at Page Load (event name)?
I needed to :
- run javascript via onload in my blazor
Normally you might have something like:
<body onload="writeConsole()">
Where writeConsole()
is a function in your JS file.
I finally got to the following code which I added to my index.razor file.
@page "/"
@inject IJSRuntime JS;
<h1>Hello, world!</h1>
Welcome to your new app.
<SurveyPrompt Title="How is Blazor working for you?" />
<canvas id="mainCanvas" width="400" height="400"></canvas>
@code{
protected override void OnInitialized()
{
}
protected override void OnAfterRender(bool firstRender)
{
JS.InvokeVoidAsync("writeConsole");
JS.InvokeVoidAsync("initGrid");
}
}
You can see that I am making two calls to two different JS methods which are defined in my JS file.
At first I thought the method that I needed to override was the OnInitialized()
but that one is actually before the page is fully "loaded" (all DOM elements are not available yet) so I use the OnAfterRender(bool firstRender)
and it worked just as if I were using the original onload
event.
The two functions I am calling take no parameters and return nothing so I use InvokeVoidAsync()
.
[Parameter]
public int StartValue { get; set; }
private int currentCount = 0;
protected override void OnInitialized() // = On Page Load
{
currentCount = StartValue;
IncrementCount();
}
private void IncrementCount()
{
currentCount++;
}
or if you don't want the first StartValue simply:
[Parameter]
public int StartValue { get; set; } = 0;
protected override void OnInitialized() // = On Page Load
{
currentCount++;
}
if you want to initialize it after component has finished rendering (maybe you want to wait for DOM to load):
[Parameter]
public int StartValue { get; set; }
private int currentCount = 0;
protected override void OnAfterRender()
{
if (firstRender)
{
currentCount = StartValue;
IncrementCount();
}
}
private void IncrementCount()
{
currentCount++;
}
There are two main ways you can do this, and either will work. I tend to prefer the first, but the second also gets the job done.
The first way, is in your @code
block, you can override the OnInitialized
method. I use the async version as you can kick off your task and let the page basics load, and then it will refresh when it gets set up.
@code {
void SomeStartupMethod()
{
// Do Some Work
}
Task SomeStartupTask()
{
// Do some task based work
return Task.CompletedTask;
}
protected override async Task OnInitializedAsync()
{
SomeStartupMethod();
await SomeStartupTask();
}
This will do work on the page load, like an initial service call to populate data, filling in lists conditionally, whatever you need to do. BTW, a trick I found is that if you put await Task.Delay(1);
as the first line of the OnInitializedAsync method body, it will break the remaining execution free from the page render, so you can get an initial and responsive page while the initial load is still processing in the background. Just something to get your page responsive faster.
The second way is to override the OnAfterRender
method, which allows the page 1 full render and then executes. It also has a default input of bool firstRender
that you can use as a condition for data loads and other things.
protected override void OnAfterRender(bool firstRender)
{
// execute conditionally for loading data, otherwise this will load
// every time the page refreshes
if(firstRender)
{
// Do work to load page data and set properties
}
}
The important thing to remember for this method is that it will execute any time the Blazor engine detects the need to refresh the UI, so use that firstRender
parameter wisely.
Depending on what you need to do, different lifecycle methods can be useful at different times, and there are a few more I haven't touched on. For further info, take a look at the official docs. I've been able to get very far on my own just using what the docs have supplied, and this link will get you started at lifecycle methods.
Hope this helps!
One important thing to note with OnInitializedAsync, is the event can fire more than once.
Depending on your application, this is probably not something you want firing over and over.
// variable in your page or component
public bool Initialized { get; set; }
// if not initialized
if (!Initialized)
{
// Do your initializations
// This way it only runs once
Initialized = true;
}
And other way is in the constructor of your Component or Page
Here I have a page named Index.razor and a code behind named Index.razor.cs
In the constructor
public void Index()
{
// Perform your initializations here
}