Calling async methods in Blazor view
AsyncComponent.razor
@typeparam TResult
@typeparam TInput
@if (Result != null)
{
@DataReadyFragment(Result)
}
else if (DataMissingFragment != null)
{
@DataMissingFragment
}
@code {
[Parameter] public RenderFragment<TResult> DataReadyFragment { get; set; }
[Parameter] public RenderFragment DataMissingFragment { get; set; }
[Parameter] public Func<TInput, Task<TResult>> AsyncOperation { get; set; }
[Parameter] public TInput Input { get; set; }
TResult Result { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if(firstRender)
AsyncOperation.Invoke(Input).ContinueWith(t => { Result = t.Result; InvokeAsync(StateHasChanged); });
}
}
Usage
<AsyncComponent TResult="User" TInput="string" Input="Pa$$W0rd" AsyncOperation="@AsyncMethodName">
<DataReadyFragment Context="result">
@if(result.IsLoggedIn)
{
<h3>Logged-In , Username:@result.Name</h3>
}
else
{
<h3>Wrong Password</h3>
}
</DataReadyFragment>
<DataMissingFragment>
<h3>Please Login :)</h3>
</DataMissingFragment>
</AsyncComponent>
Related videos on Youtube
A.A
Updated on June 04, 2022Comments
-
A.A almost 2 years
I have a server-side blazor client and I'm trying to modify the MainLayout razor page by having a Login check. I'm currently using Blazored for localstorage saving, and I'm currently using to see if a token is saved to see if user is logged in, however I'm not sure how I translate this in the if statement in razor page because it wants async method.
My login check is pretty simple as shown below.
public async Task<bool> IsLoggedIn() { return await m_localStorage.ContainKeyAsync("token").ConfigureAwait(false); }
In my Razor page I'm doing this statement check - which obvious doesn't work as there's no async modifier
@if (!await AppState.IsLoggedIn()) //Requires async modifier { <a href="Login" target="_blank">Login</a> }
I've also tried doing it using the .Result property, but this results in an exception thrown: (System.AggregateException: 'Information: Executed an implicit handler method, returned result Microsoft.AspNetC)' with an inner-exception -> NullReferenceException: Object reference not set to an instance of an object.
But from what I can see AppState is injected correctly and the local storage seems to be injected correctly in AppState.
@if (!AppState.IsLoggedIn().Result) { <a href="Login" target="_blank">Login</a> }
So my question is what is the correct way to approach this, is there a way to execute async methods in razor pages?
-
Bronzato almost 4 yearsGood job. But i had to change a little bit: if (firstRender) { await AsyncOperation.Invoke(Input).ContinueWith(t => { Result = t.Result; InvokeAsync(StateHasChanged); }); } Otherwize it loops endless....
-
Al-Hanash Moataz almost 4 years@Bronzato yes you right , i forgot to add that line of code. I’ll update my answer
-
The Sharp Ninja over 2 yearsThis blows up at runtime in WASM.
-
The Sharp Ninja over 2 yearsBlows up at runtime in WASM.
-
WebGeek over 2 yearsCan't comment regarding WASM, this works server-side Blazor which was specified in the question. With WASM some things have a different solution.