Could not find 'ShowToastr' ('ShowToastr' was undefined). Blazor

484 Views Asked by At

I get this error: Could not find 'ShowToastr' ('ShowToastr' was undefined). I am creating a Blazor app with .NET6. This is the page:

@page "/hotel/rooms"
@inject ILocalStorageService localStorage
@inject IJSRuntime jsRuntime
@inject IHotelRoomService hotelRoomService

<h3>HotelRooms</h3>

@code {
    private HomeViewModel HomeModel { get; set; } = new HomeViewModel();
    public IEnumerable<HotelRoomDto> Rooms { get; set; } = new List<HotelRoomDto>();

    protected override async Task OnInitializedAsync()
    {
        try
        {
            if (await localStorage.GetItemAsync<HomeViewModel>(SD.Local_InitialBooking) != null)
            {
                HomeModel = await localStorage.GetItemAsync<HomeViewModel>(SD.Local_InitialBooking);
            }
            else
            {
                HomeModel.NumberOfNights = 1;
            }
            await LoadRooms();
        }
        catch (Exception ex)
        {
            await jsRuntime.ToastrError(ex.Message);
        }
    }

common.js :

window.ShowToastr = (type, message) => {
    if (type === "success") {
        toastr.success(message, "Operation Successful")
    }
    if (type === "error") {
        toastr.error(message, "Operation Failed")
    }
}

I have two references on ToastrError :

public static class IJSRuntimeExtension
    {
        public static async ValueTask ToastrSuccess(this IJSRuntime JSRuntime, string message)
        {
            await JSRuntime.InvokeVoidAsync("ShowToastr", "success", message);
        }

        public static async ValueTask ToastrError(this IJSRuntime JSRuntime, string message)
        {
            await JSRuntime.InvokeVoidAsync("ShowToastr", "error", message);
        }
    }

While debugging HotelRooms.razor the whole try block passes, the LoadRooms(the method is entered) and after that the debugger enters the catch block where I get this error.

This is the index.html file:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <title>HiddenVilla_Client</title>
    <base href="/" />
    <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
    <link href="css/app.css" rel="stylesheet" />
    <link href="HiddenVilla_Client.styles.css" rel="stylesheet" />
    <link href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css" rel="stylesheet" />

</head>

<body>
    <div id="app">
        <div style="position:fixed;top:50%;left:50%;margin-top:-50px;margin-left:-100px;">
            <img src="images/ajax-loader.gif" />
        </div>
    </div>

    <div id="blazor-error-ui">
        An unhandled error has occurred.
        <a href="" class="reload">Reload</a>
        <a class="dismiss"></a>
    </div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg==" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.js" integrity="sha512-VEd+nq25CkR676O+pLBnDW09R7VQX9Mdiij052gVCp5yVH3jGtH70Ho/UUv4mJDsEdTvqRCFZg0NKGiojGnUCw==" crossorigin="anonymous"></script>
    <script src="https://js.stripe.com/v3/" defer></script>
    <script src="js/common.js"></script>
    <script src="_framework/blazor.webassembly.js"></script>
</body>

</html>
2

There are 2 best solutions below

5
Surinder Singh On

Please move ShowToastr to OnAfterRender event, this is the event when UI is fully ready and accessible.

0
el sonero menor On

In index.html "you already have it" link the toastr cdns

In your common.js

function  toastrSuccess(message){
  toastr.success(message);
}
function  toastrError(message){
  toastr.error(message);
}

your component

@page "/hotel/rooms"
@inject ILocalStorageService localStorage
@inject IJSRuntime jsRuntime
@inject IHotelRoomService hotelRoomService

<h3>HotelRooms</h3>

@code {
    private HomeViewModel HomeModel { get; set; } = new HomeViewModel();
    public IEnumerable<HotelRoomDto> Rooms { get; set; } = new List<HotelRoomDto>();

    protected override async Task OnInitializedAsync()
    {
        try
        {
            if (await localStorage.GetItemAsync<HomeViewModel>(SD.Local_InitialBooking) != null)
            {
                HomeModel = await localStorage.GetItemAsync<HomeViewModel>(SD.Local_InitialBooking);
            }
            else
            {
                HomeModel.NumberOfNights = 1;
            }
            await LoadRooms();
           //example of using toastr success
              await jsRuntime.InvokeVoidAsync("toastrSuccess","what ever you want in success toastr");
        }
        catch (Exception ex)
        {
            await jsRuntime.InvokeVoidAsync("toastrError",ex.Message);
        }
    }

References