misterbee180
misterbee180

Reputation: 381

blazor WASM new select options refresh slower than assignment of new bind value

I have a select dropdown which I populate content for via a foreach loop off of a list. In one circumstance I want to be able to add a new option to that list and then select that new option. I'm able to add the new value to the list and I'm able to assign the binded property it's new value. I have comments in the output which show the variables are as they should be.

However the UI is not updating prior to the binded property attempting to trigger an on change event leading to the select not selecting the new value but instead what ever the first value of the list is.

I've tried calling stateHasChanged() immediately after updating the list but that doesn't seem to change anything. The specific scenarios logic is occurring in an async Task fired from a button click.

Logic to update the list:

async Task SaveProfile(){
   Profiles.Insert(Profiles.Count - 1, new TableConfiguration() { ConfigurationId = NewProfile });
   StateHasChanged();
   ProfileDecode = NewProfile;
}

Select UI Logic:

<select @bind=ProfileDecode class="form-control-sm">
            @foreach (var prof in Profiles)
            {
                <option>@prof.ConfigurationId</option>
            }
        </select>

ProfileDecode property

private string ProfileDecode
        {
            get { return SelectedProfile.ConfigurationId; }
            set
            {
                Console.WriteLine("passed value:" + value + " current value:" + ProfileDecode);
                if (SelectedProfile.ConfigurationId != value)
                {
                    
                    SelectedProfile = Profiles.Single(p => p.ConfigurationId == value);
                }
            }
        }

Upvotes: 2

Views: 890

Answers (1)

MrC aka Shaun Curtis
MrC aka Shaun Curtis

Reputation: 30177

I'm struggling a little to put together a working model based on the code snippets you've provided. Someone else may figure it out: if they do I'll happily delete this answer.

So, I've built what I believe is a basic replica of what you are trying to achieve as a single Razor page.

This works. If this doesn't properly mimic what you have, please alter it so that it does, so we can help get to the bottom of the problem.

@page "/"

<PageTitle>Index</PageTitle>

<select @bind="selectedItem" class="form-select">
    @foreach (var country in Countries)
    {
        if (country == selectedItem) selectCountry = true;
        else selectCountry = false;
       
        <option @key= "country" selected="@selectCountry" value=country>@country</option>

}
</select>


<div class="m-2">
    <div class="row">
        <div class="col-6">
            <input class="form-control form-text" type="text" @bind-value=this.newCountry />
        </div>
        <div class="col-6">
            <button class="btn btn-dark" @onclick=this.AddToList>Add To List</button>
        </div>
    </div>
</div>

@code {
    private string selectedItem = string.Empty;

    private string newCountry = string.Empty;
    private bool selectCountry = false;


    private List<string> Countries = new List<string> { "UK", "France", "Spain" };

    private async Task AddToList()
    {
        // mimic some async action such as a Db or api get
        await Task.Delay(100);
        if (!string.IsNullOrWhiteSpace(this.newCountry))
        {
            //Countries.Add(newCountry);

            Countries.Insert(Countries.Count - 1, newCountry);
            selectedItem = newCountry;
        }
    }
}

Upvotes: 3

Related Questions