Calling async methods in Blazor view

11,823

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>
Share:
11,823

Related videos on Youtube

A.A
Author by

A.A

Updated on June 04, 2022

Comments

  • A.A
    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
    Bronzato almost 4 years
    Good 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
    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
    The Sharp Ninja over 2 years
    This blows up at runtime in WASM.
  • The Sharp Ninja
    The Sharp Ninja over 2 years
    Blows up at runtime in WASM.
  • WebGeek
    WebGeek over 2 years
    Can't comment regarding WASM, this works server-side Blazor which was specified in the question. With WASM some things have a different solution.