1

I'm trying to create a Blazor webassambly page where about 8 filter states are stored and synchronised as query parameters.

Currently, the below sample page supports that when I request /orders?status=uploading the status is preset with Uploading and when I choose another value in the InputSelect the state is updated on the Status property on the model.

But further, when choosing another value in the InputSelect, I would like the URL to update to reflect that (without reloading the page).

How is best practices for updating the URL to always reflect the state of the page (with multiple parameters)?

@page "/orders"

<PageTitle>Navigation demo</PageTitle>

<EditForm Model="_model">
    <InputSelect @bind-Value="_model.Status">
        @foreach (var orderStatus in Enum.GetValues(typeof(OrderStatus)))
        {
            <option value="@orderStatus">@orderStatus</option>
        }
    </InputSelect>
</EditForm>

Selected status: @_model.Status

@code {

    public enum OrderStatus
    {
        Created,
        Uploading,
        Uploaded
    }

    readonly Model _model = new();

    class Model
    {
        public OrderStatus Status { get; set; }
    }

    [Parameter]
    [SupplyParameterFromQuery(Name = "status")]
    public string? StatusString
    {
        get => _model.Status.ToString();
        set
        {
            var couldParse = Enum.TryParse(value, true, out OrderStatus newStatus);
            if (couldParse)
            {
                _model.Status = newStatus;
            }
        }
    }

}

2 Answers 2

4

Here's some demo code that demonstrates how to update the Url. Note the code comments on what get's hit when. On navigating to the same route, only OnParametersSet{Async} gets hit.

@page "/"
@inject NavigationManager NavManager

<PageTitle>Index</PageTitle>

<select class="form-select" @bind=this._model.Status >
    <option value="Created">Created</option>
    <option value="Uploading">Uploading</option>
    <option value="Uploaded">Uploaded</option>
</select>
<button class="btn btn-dark" @onclick=SetStatus>Select</button>

@code {
    private string status = string.Empty; 

    public enum OrderStatus
    {
        Created,
        Uploading,
        Uploaded
    }

    readonly Model _model = new();

    class Model
    {
        public OrderStatus Status { get; set; }
    }

    [Parameter]
    [SupplyParameterFromQuery(Name = "status")]
    public string? StatusString { get; set; }

    protected override void OnInitialized()
    {
        // I'm only hit on first load
        base.OnInitialized();
    }

    protected override void OnParametersSet()
    {
        // I'm hit every time
        base.OnParametersSet();
    }

    private void SetStatus()
    {
        NavManager.NavigateTo($"/?status={this._model.Status}");
    }
}

Sign up to request clarification or add additional context in comments.

Comments

3

Just leaving this here for the next person looking for this, as of .NET 6, you're able to use an override to update/replace URI parameters easily.

Make sure you inject a NavigationManager

@inject NavigationManager nav

Now anywhere else in your code:

//Update the id query param with a new value. Super easy!
nav.NavigateTo(nav.GetUriWithQueryParameter("id", NewID), false, true);

There's also a GetUriWithQueryParameters for multiple values.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.