NeuroAgent

ServiceStack Blazor AutoQueryGrid Toast Notifications Guide

Complete guide to implementing toast notifications in ServiceStack Blazor AutoQueryGrid for better user feedback after create, update, and delete operations.

Question

How to Display Toast Notifications After CRUD Operations in ServiceStack Blazor Using AutoQueryGrid

I’m using the ServiceStack Server Blazor project template with the AutoQueryGrid component configured as follows:

html
<AutoQueryGrid Model="Booking" Apis="Apis.AutoQuery<QueryBookings,CreateBooking,UpdateBooking,DeleteBooking>()" />

I want to display toast notifications to users after each CRUD operation (Create, Read, Update, Delete) is completed. I’ve tried using the DataLoaded event as shown below:

html
@page "/bookings"
@using ServiceStack.Blazor
@Inject ToastService Toast

Bookings
<AutoQueryGrid Model="Booking" Apis="Apis.AutoQuery<QueryBookings,CreateBooking,UpdateBooking,DeleteBooking>()" DataLoaded="OnDataLoaded"/>

@code {
    bool _firstLoad = true;
    async Task OnDataLoaded(List<Booking> bookings)
    {
        // Skip showing a toast on the initial page load
        if (_firstLoad)
        {
            _firstLoad = false;
            return;
        }

        await Toast.Success("✅ Operation completed successfully!");
    }
}

However, this approach doesn’t work as expected. The toast notification doesn’t appear after CRUD operations. I’m using ServiceStack version 8.9.0 and prefer not to use a custom edit form template.

What is the correct way to implement toast notifications after CRUD operations using the AutoQueryGrid component in ServiceStack Blazor? Are there built-in events I should be using instead, or is there a way to create custom events for the component?

NeuroAgent

The correct approach to display toast notifications after CRUD operations in ServiceStack Blazor using AutoQueryGrid is to use the built-in operation-specific events like OnCreate, OnUpdate, and OnDelete rather than the DataLoaded event, as these events specifically trigger after each respective CRUD operation completes, allowing you to show appropriate toast notifications.

Contents

Understanding AutoQueryGrid Events

The AutoQueryGrid component in ServiceStack Blazor provides several built-in events that fire specifically after CRUD operations, which is exactly what you need for displaying toast notifications. Unlike the DataLoaded event that triggers whenever data is loaded (including initial page loads and refreshes), the operation-specific events allow you to target the exact moment when a user action completes.

The DataLoaded event is meant for general data loading scenarios and doesn’t distinguish between different types of operations. This is why your current approach doesn’t work as expected - the event fires on initial load and you can’t easily differentiate between a CRUD operation and a simple data refresh.

Built-in CRUD Operation Events

AutoQueryGrid exposes the following operation-specific events that you can utilize for toast notifications:

  • OnCreate - Fires after a new record is successfully created
  • OnUpdate - Fires after an existing record is successfully updated
  • OnDelete - Fires after a record is successfully deleted
  • OnSave - Fires after any save operation (create or update)

These events provide the perfect hooks for displaying toast notifications because they specifically trigger when the user completes a CRUD action, not just when data is loaded.

Key Insight: The operation-specific events pass relevant data that you can use to customize your toast messages, such as the affected record or operation results.

Implementation with Toast Notifications

Here’s the correct implementation using the built-in operation events:

html
@page "/bookings"
@using ServiceStack.Blazor
@inject ToastService Toast

<h3>Bookings Management</h3>
<AutoQueryGrid 
    Model="Booking" 
    Apis="Apis.AutoQuery<QueryBookings,CreateBooking,UpdateBooking,DeleteBooking>()"
    OnCreate="OnCreateCompleted"
    OnUpdate="OnUpdateCompleted"
    OnDelete="OnDeleteCompleted"/>

@code {
    async Task OnCreateCompleted(Booking createdBooking)
    {
        await Toast.Success($"✅ Booking '{createdBooking.Id}' created successfully!");
    }

    async Task OnUpdateCompleted(Booking updatedBooking)
    {
        await Toast.Info($"📝 Booking '{updatedBooking.Id}' updated successfully!");
    }

    async Task OnDeleteCompleted(Booking deletedBooking)
    {
        await Toast.Warning($"🗑️ Booking '{deletedBooking.Id}' deleted successfully!");
    }
}

Key Benefits of This Approach:

  1. Specific Event Handling: Each event fires only after the corresponding CRUD operation
  2. Contextual Information: Events provide the affected record, allowing for personalized messages
  3. Clean Separation: No need to track initial loads or manually filter operations
  4. Better User Experience: Immediate feedback for each user action

Alternative Approaches

Using the DataGrid Underlying Events

Since AutoQueryGrid is built on top of the DataGrid component, you can also access lower-level events:

html
<AutoQueryGrid ...>
    <ChildContent>
        <DataGrid @ref="DataGrid" ... />
    </ChildContent>
</AutoQueryGrid>

Then handle events from the underlying DataGrid component.

Custom Event Handlers

For more complex scenarios, you can create custom event handlers:

csharp
public partial class MyAutoQueryGrid<T> : AutoQueryGrid<T>
{
    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();
        // Subscribe to internal events
    }
    
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await base.OnAfterRenderAsync(firstRender);
        // Additional event setup
    }
}

Complete Example with Enhanced Features

Here’s a more complete implementation with additional features:

html
@page "/bookings"
@using ServiceStack.Blazor
@inject ToastService Toast

<h3>Bookings Management</h3>

<AutoQueryGrid 
    Model="Booking" 
    Apis="Apis.AutoQuery<QueryBookings,CreateBooking,UpdateBooking,DeleteBooking>()"
    OnCreate="OnCreateCompleted"
    OnUpdate="OnUpdateCompleted"
    OnDelete="OnDeleteCompleted"
    OnSave="OnSaveCompleted"
    OnError="OnErrorOccurred"/>

@code {
    async Task OnCreateCompleted(Booking createdBooking)
    {
        await Toast.Success(
            $"✅ Booking created successfully!", 
            $"ID: {createdBooking.Id}",
            "success"
        );
    }

    async Task OnUpdateCompleted(Booking updatedBooking)
    {
        await Toast.Info(
            $"📝 Booking updated successfully!", 
            $"ID: {updatedBooking.Id}",
            "info"
        );
    }

    async Task OnDeleteCompleted(Booking deletedBooking)
    {
        await Toast.Warning(
            $"🗑️ Booking deleted successfully!", 
            $"ID: {deletedBooking.Id}",
            "warning"
        );
    }

    async Task OnSaveCompleted(Booking savedBooking)
    {
        // This fires for both create and update
        await Toast.Show(
            $"💾 Booking saved successfully!",
            $"ID: {savedBooking.Id}",
            "save"
        );
    }

    async Task OnErrorOccurred(Exception ex)
    {
        await Toast.Error(
            $"❌ Operation failed!", 
            ex.Message,
            "error"
        );
    }
}

Toast Configuration Tips:

  1. Use Different Types: Utilize different toast types (Success, Info, Warning, Error) to distinguish between operations
  2. Include Details: Add contextual information like record IDs for better user feedback
  3. Handle Errors: Include error handling for failed operations
  4. Custom Styling: Use custom toast classes if needed

Conclusion

To implement toast notifications after CRUD operations in ServiceStack Blazor using AutoQueryGrid:

  1. Use Operation-Specific Events: Replace the DataLoaded event with OnCreate, OnUpdate, and OnDelete events that specifically trigger after each CRUD operation
  2. Leverage Event Parameters: These events provide the affected record object, allowing for personalized toast messages
  3. Add Error Handling: Include the OnError event to handle and display operation failures
  4. Consider User Experience: Use different toast types (Success, Info, Warning) to distinguish between different operation types

This approach provides clean, targeted event handling that gives users immediate feedback after each CRUD operation, significantly improving the user experience of your Blazor application.

Sources

  1. AutoQueryGrid Component Source Code - ServiceStack GitHub
  2. ServiceStack Blazor Components Documentation
  3. Blazor Toast Notifications Tutorial
  4. ServiceStack v6.4 Release Notes
  5. Blazor Auto Template Documentation