Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript interop Error when calling javascript from OnInitializedAsync Blazor

I am following a sample app from the NDC Oslo which is this app: https://github.com/SteveSandersonMS/presentation-2019-06-NDCOslo/tree/master/demos/MissionControl. This implements JWT as authentication and authorization. However when I tried to copy the implementation of the code to a Server Side Blazor, I'm getting an error when I try to get the JWT token stored from the local storage described below"

JavaScript interop calls cannot be issued at this time. This is because the component is being 
statically rendererd. When prerendering is enabled, JavaScript interop calls can only be performed 
during the OnAfterRenderAsync lifecycle method.

Here is my blazor code

protected override async Task OnInitializedAsync()
{
    var token = await TokenProvider.GetTokenAsync();
    Branches = await Http.GetJsonAsync<List<BranchDto>>(
        "vip/api/lookup/getbranches",
        new AuthenticationHeaderValue("Bearer", token));
}

The error comes from

public async Task<string> GetTokenAsync()
{
   //Code Omitted for brevity 
   //This line of code is equivalent to the IJSRuntime.Invoke<string>("localstorage.getitem","authToken") 
   //change to use Blazore.LocalStorage.
    var token = await _localStorageService.GetItemAsync<string>("authToken");
    return token;
 }

I tried perform the code on OnAfterRenderAsync(bool firstRender) and the error is gone but the grid which is binded to the API request has no display. The API request must fill the data source for the grid which must be OnInitializedAsync. Any workaround on this?

Update! I moved the code OnAfterRenderAsync and added the StateHasChanged Method and I got the desired Behavior. I forgot that the connection for rendering was a signalR connection.

like image 978
Edu Cielo Avatar asked Apr 26 '20 09:04

Edu Cielo


People also ask

Can you use JavaScript in Blazor?

A Blazor app can invoke JavaScript (JS) functions from . NET methods and . NET methods from JS functions. These scenarios are called JavaScript interoperability (JS interop).

Why Blazor is not popular?

Blazor projects are slow on the client-side because you have to download the entire dot net runtime along with the necessary DLL libraries on your browser. Additionally, Blazor apps have latency issues.

Is Blazor Transpiled to JavaScript?

As with JavaScript, it is possible to use TypeScript in a Blazor project. After all, TypeScript is a superset of JavaScript, it builds on it and it is officially supported by Microsoft. When compiling your Blazor project, your TypeScript code will be transpiled into JavaScript and both files will live with each other.

Should I use Blazor server or Blazor Wasm?

The Blazor Server hosting model offers several benefits: Download size is significantly smaller than a Blazor WebAssembly app, and the app loads much faster. The app takes full advantage of server capabilities, including the use of . NET Core APIs.


1 Answers

As per “Detect when a Blazor Server app is prerendering”, you can only safely run interop code in the OnAfterRenderAsync lifecycle method.

However, since this runs after the render cycle, you will need to notify your component to re-render using StateHasChanged() once your asynchronous process completes:

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender)
    {
        var token = await TokenProvider.GetTokenAsync();
        Branches = await Http.GetJsonAsync<List<BranchDto>>(
            "vip/api/lookup/getbranches",
            new AuthenticationHeaderValue("Bearer", token));

        StateHasChanged();
    }
}
like image 81
poke Avatar answered Oct 09 '22 23:10

poke