Link to GitHub for quick access to minimum reproducible example (code is provided below, as well): https://github.com/thecodeiackiller/cascadingSelectListProblem
- #1) I have a list of workouts.
- #2) I have 2 enums (WorkoutType & ExerciseType) that filter the list of workouts.
- #3) I have an EditForm which allows the user to:select the WorkoutType (LowerBody or UpperBody), which filters a list of exercises andselect the ExerciseType (Main, Secondary, Accessory), which filters the list even further.
Note: For those unfamiliar with the fitness arena, in a given workout, you typically have a workout type (Leg day, upper body, etc.) and within that workout, you have exercise types (your main/heavier exercises, your secondary exercises, and your accessory exercises (working the small muscles).
Expected Chronological User Flow:
- WorkoutType is selected and list of exercises is filtered (I believe my form is already successfully doing that).
- For first row in the EditForm, user selects an ExerciseType (main,secondary,accessory) and list is filtered again.
- User selects Name of an exercise for the now twice-filtered list. Still in first row.
- User navigates to second row.
- User selects ExerciseType
- User selects new exercise Name from list (which should be filtered based on the selected ExerciseType for second row).
Problem: List of exercise Names DOES NOT update for the second row. The list of exercise names remains the same as the first exercise, even though the ExerciseTypes are different, which should change the exercises that show up.
AddWorkout.razor component for my current implementation:
@using stateManagementMinimumReproducibleExample.Repositories@using stateManagementMinimumReproducibleExample.Models@page "/addworkout"@rendermode InteractiveServer@inject UserExerciseRepository userExerciseRepository<EditForm Model="userExercise"><label for="workoutType"> Workout Type: </label><InputSelect id="workoutType" @bind-Value="userExercise.WorkoutType" @bind-Value:after="GetExercisesByWorkoutType"> @foreach (var type in Enum.GetValues(typeof(WorkoutType))) {<option value="@type">@type</option> }</InputSelect> @for (int i = 0; i < numberOfExercisesInWorkout; i++) { var j = i; if (j >= exerciseListForSelectedDay.Count) { exerciseListForSelectedDay.Add(new UserExercise()); }<div><label for="exerciseType"> Exercise Type: </label><InputSelect id="exerciseType" @bind-Value="exerciseListForSelectedDay[j].ExerciseType" @bind-Value:after="GetExercisesByExerciseType"> @foreach (var type in Enum.GetValues(typeof(ExerciseType))) {<option value="@type">@type</option> }</InputSelect><label for="exerciseName"> Exercise: </label><InputSelect id="exerciseName" @bind-Value="exerciseListForSelectedDay[j].ExerciseId"> @foreach (var exercise in listOfExerciseByExerciseType) {<option value="@exercise.Id">@exercise.Name</option> }</InputSelect></div> }</EditForm>@code { private int numberOfExercisesInWorkout = 2; private UserExercise userExercise = new(); private List<UserExercise> exerciseListForSelectedDay = new(); public List<Exercise> listOfExercisesByWorkoutType = new(); public List<Exercise> listOfExerciseByExerciseType = new(); public async Task GetExercisesByWorkoutType() { listOfExercisesByWorkoutType = await userExerciseRepository.GetExercisesBasedOnWorkoutType(userExercise.WorkoutType); StateHasChanged(); } public void GetExercisesByExerciseType() { listOfExerciseByExerciseType = userExerciseRepository.GetExercisesFromWorkoutListBasedOnExerciseType(listOfExercisesByWorkoutType, userExercise.ExerciseType);; }}I have thought about the possibility of creating a dictionary the store the the list of exercises for each exercise within the workout. In addition, I've thought storing a List as a property in my UserExercise class, and then adding the filtered list of exercises to the property. I'm not sure exactly what path I should go down or if there were any potential Blazor-specific state management alternatives that were out there.
The code above should give you enough information to diagnose the problem. If you need a visual, here are the steps to quickly reproduce problem after forking and cloning the GitHub repo:
- Start app
- Navigate to /addworkout endpoint
- Select a WorkoutType (for entire form)
- Select an ExerciseType (for first row)
- Select an Exercise (for first row)
- Select an ExerciseType (for second row)
- Select an Exercise (for second row)
At this point you'll see that the filtered list has not updated for the second row based on the selection of a different ExerciseType than that of the first row. How can I get the appropriate list(s) of exercises to appear for the second (and beyond)? Thank you.