Passing variables to Strawberry Shake Components in Blazor

/images/2024/01/Designer.jpeg

In my last blog post (StrawberryShake in Blazor) I went through setting up simple displaying of data from graphql using Chilicream Client-creating-library Strawberry Shake for Blazor.

That was just simple select with no interaction or input but that was one of my questions in the end “How do I pass variables into these components?”.

Now I’ll try to address that

Add filtering

When adding a query (see next step) using where conditions I just got errors complaining it wasn’t valid keyword!

What I had to do was to add the [UseFiltering] attribute to my query like this

[UsePaging]
[UseFiltering]
public IQueryable<Customer> GetCustomer(
   MasterDataContext context)
   => context.Customers.OrderBy(t => t.Id);

Add a .graphql query taking id

Now create GetCustomerById.graphql in your Blazor project and add the following

query GetCustomersById($id: Int) {
  customer(where: { id: { eq: $id } }) {
    nodes {
      id
      name
    }
  }
}

the $id is a parameter that feeds into the query.

Btw if you are using Fusion then you need to pack and compose your schema before recreating your Straweberry Shake client.

Blazor schema.graphql

This file needs to contain the updated schema so the client gets created (see (StrawberryShake in Blazor)).

How I do it (must be another way?) is to run the following command (I got errors skipping init)

dotnet graphql init http://localhost:20999/graphql/ -n GatewayClient

and then undoing the changes to .graphqlc.json file.

Now your schema.graphql file should contain CustomerFilterInput

Running the following

dotnet build

Will now give you an updated client with UseGetCustomersById component in it.

Add component to page

Here is the generated component on a page fetching data when a drop down is changed.

The drop down is populated on OnInitializedAsync() by using the client like this GatewayClient.GetCustomers.ExecuteAsync().

@page "/GetCustomersById"
@using YourNamespace.Gateway  @* you need this here or in _Import.razor *@
@inject GatewayClient GatewayClient

@* To get all the customers we use the GatewayClient in OnInitializedAsync() *@
<select @onchange="OnCustomerSelected">
    <option value="0">Select</option>
    @foreach (var customer in customers)
    {
        <option value="@customer.Id">@customer.Name</option>
    }
</select>

@* 
   Using ExecutionStrategy.CacheFirst will first hit the gateway and subgraph but then cache the results so next ones.
   It caches for each id passed in! There are two more strategies CacheAndNetwork and NetworkOnly.
*@
<UseGetCustomersById Context="result" Id=@selectedCustomerId Strategy="ExecutionStrategy.CacheFirst">
    <ChildContent>

        @if (selectedCustomerId != 0)
        {
            @if (result.Customer?.Nodes is not null)
            {
                @foreach (var customer in result.Customer.Nodes)
                {
                    <p>@customer.Name</p>
                }
            }
        }
        else
        {
            <p>Select one customer that are in the dropdown!</p>
        }
    </ChildContent>
    <ErrorContent>
        Something went wrong ...<br />
        @result.First().Message
    </ErrorContent>
    <LoadingContent>
        Loading ...
    </LoadingContent>
</UseGetCustomersById>

@code {

protected override async Task OnInitializedAsync()
{
    // Use the GatewayClient to get all customers for the dropdown
    var result = await GatewayClient.GetCustomers.ExecuteAsync();
    if (result.IsSuccessResult() && result.Data?.Customer?.Nodes != null)
    {
        customers = result.Data.Customer.Nodes.Select(node => 
        new CustomerDropdownModel { Id = node.Id, Name = node.Name! }).ToList();
    }
}

public class CustomerDropdownModel
{
    public int Id { get; set; }
    public required string Name { get; set; }
}

List<CustomerDropdownModel> customers = new();
int selectedCustomerId = 0;

// This is called when the user selects a customer in the dropdown
void OnCustomerSelected(ChangeEventArgs e)
{
    selectedCustomerId = Convert.ToInt32(e.Value);
}
}

I won’t break down the example any further since with the comments it should be fairly self explanatory.

Final words

I will be continuing my exploration of Strawberry Shake and Fusion and posting about it so stay tuned!

Latest Posts