0

I am using a Blazor Web App. I have an Enum. It has three values: UpperBody, LowerBody, FullBody. My goal is to have a user select one of these values. Afterwards, the program will take that selected value (UpperBody, LowerBody, FullBody) and filter exercises from a database based on the value. This requires the selected enum value to successfully bind to a variable within my component. I have not found a way to do this. As you'll see in my code, I also have a method that is meant to print the selected enum value to the console. Furthermore (as you'll see), I'm trying to print the value of the Enum within the HTML. This is for debugging so that I can "see" my updated value.

The Enum:

namespace dataBindingProblem
{
    public enum WorkoutType
    {
        UpperBody, LowerBody, FullBody
    }
}

The Component:

NOTE: This code block is missing the EditForm tag. For that reason, upon navigating to the /selectworkout endpoint, you will run into an exception stating that EditContext or Model needs to be used. I'm not sure how to proceed with this as I'm not dealing directly with a Model (Although I did try introducing one as explained below).

@page "/selectworkout"

<h3>Select Workout Type (From Enum Values) </h3>


    <label for="workoutselection"> Select Workout Type </label>
    <InputSelect id="workoutselection" @bind-Value="@selectedWorkoutType" @bind-Value:after="workoutTypeChanged">
        <option value=""> Select Workout Type </option>
        @foreach (var type in Enum.GetValues(typeof(WorkoutType)))
        {
            <option value="@type">@type</option>
        }
    </InputSelect>


<p>Selected Workout Type: @selectedWorkoutType</p>

@code {
    private WorkoutType selectedWorkoutType;

    public void workoutTypeChanged()
    {
        Console.WriteLine($"Workout Type Changed: {selectedWorkoutType}");
    }
}

Things I have tried

  • I have tried refactoring my Component to introduce a UserExercise.cs model (as stated above) which has the property public WorkoutType WorkoutType {get; set;}. In this attempt, I also introduced EditContext into the EditForm tag.This attempt was inspired by this.

  • I tried using ValueChanged parameter in the InputSelect tag. After further inspection, I replaced that with bind-Value:after, inspired by the 2023 solution by jeroba.

  • I have tried stepping away from the computer and going to Qdoba to get a burrito bowl.

In addition to solving the problem, if there are any recommendations to debug something like this in the future, please enlighten me. Bottom line, I just want to get to bind to work. I thought about refactoring the app and removing the enums all together and introducing an in-memory List for the drop-down and ultimately to filter the database, but I don't think its the enums (and their associated models) that are causing the trouble. Thank you.

1 Answer 1

0

The simplest way is to introduce a local model. WorkoutType can be null, as it would appear that's what you want [you have a Select Workout Type option].

Here's some demo code. I've also added some display logic to handle Select Workout Type option so it can't be selected and only shows when the value is null.

@page "/"

<h3>Select Workout Type (From Enum Values) </h3>

<EditForm Model="_model">
    <label class="form-label"> Select Workout Type </label>
    <InputSelect class="form-select" @bind-Value="@_model.WorkoutType" @bind-Value:after="workoutTypeChanged">
        @if(_model.WorkoutType is null)
        {
            <option disabled="true" selected value=""> Select Workout Type </option>
        }
        @foreach (var type in Enum.GetValues(typeof(WorkoutType)))
        {
            <option value="@type">@type</option>
        }
    </InputSelect>
</EditForm>

<div class="bg-dark text-white m-2 p-2">
    <pre>Selected Workout Type: @_model.WorkoutType</pre>
</div>

@code {
    private Model _model = new();

    public void workoutTypeChanged()
    {
        Console.WriteLine($"Workout Type Changed: {_model.WorkoutType}");
    }

    public enum WorkoutType
    {
        UpperBody, LowerBody, FullBody
    }

    private class Model
    {
        public WorkoutType? WorkoutType { get; set; }
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

This did not work until I put the appropriate render mode directive in my component ( @rendermode InteractiveServer). Afterwards, this worked as intended and so did another refactored example which used a shared class and enum within the same project but outside of the component. Thanks, Shaun.
NP. You didn't provide enough info on your setup to make that connection :-)

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.