1

Having some issues with a foreach loop in my Blazor page. I'm trying to have an input dropdown of paints and let the user select from it. However, when I select a paint in the dropdown it doesn't actually bind to the input field. I know the logic for the dropdown should work as I've used it on another page where it works fine. I'm using a local temp variable as I can't change elements in a foreach loop. I also cannot use a for loop, as I get index out-of-bounds errors, which I guess has to do with getting the count and render times. If anyone has a better suggestion, I'd love to hear it! The code block is below and here is also a link to my repo if you need more context. Thanks in advance!

foreach (var elem in newMini.Elements)
                {
                    <div class="@elem.Name">
                        <InputText @bind-Value="elem.Name" placeholder="Element name" />
                        @foreach (var paintUsed in elem.PaintsUsed)
                        {
                            var curPaintUsed = paintUsed;
                            <div class="@curPaintUsed">
                                current paint: @curPaintUsed 
                                <input type="text"
                                       list="paint-search"
                                       placeholder="Search from @allPaints.Count() paints!"
                                       @bind-value="@curPaintUsed" />
                                <datalist id="paint-search">
                                    @foreach (var paint in allPaints)
                                    {
                                        <option>@paint.PaintName</option>
                                    }
                                </datalist>
                            </div>
                        }
                        @if (!String.IsNullOrWhiteSpace(elem.Name))
                        {
                            <button type="button" @onclick="() => AddPaintToElement(elem)">
                                Add Paint To Element
                            </button>
                        }
                    </div>
                }
2
  • Using a local variable curPaintUsed is superfluous and thus misleading. Please remove it. I believe the issue is related to the fact that you're using an input element ( @bind-value="@curPaintUsed" ) instead of InputText component, so no binding because you use EditForm component with a model, right ? The issue may be here. Please, provide complete repro of your code Commented Sep 25, 2021 at 19:20
  • Changing it to InputText unfortunately didn't help. If I remove the curPaintUsed I get an error that I cannot assign to curPaintUsed because it is a 'foreach iteration variable'. Which was why I originally tried to use a for loop vice foreach. Here's the link to my repo github.com/Zami77/wargamer_showcase The specific page is at pages/miniupload.razor Thanks again for the help! Commented Sep 25, 2021 at 19:44

1 Answer 1

2

I've inspected your code superficially, but I believe that the following will solve your issue. Try to do as suggested below, and if it still doesn't work, I'll try to solve it tomorrow.

  1. Use InputText component as suggested previously.

  2. This @foreach (var paintUsed in elem.PaintsUsed) can never work as you're trying to bind to a collection of string using 'foreach iteration variable.' Instead define a class, let's call it PaintsUsedStrings, like the following

    public class PaintsUsedStrings { public string StringValue { get; set; } }

and in your MiniElement class change the property

public List<String> PaintsUsed { get; set; } = new();

to:

public List<PaintsUsedStrings> PaintsUsed { get; set; } = new();

And change the code in your component to something like this:

 @foreach (var _paintsUsedStrings in elem.PaintsUsed)
    {
        current paint: @_paintsUsedStrings.StringValue 
        <InputText list="paint-search" placeholder="Search from <...> 
                                                             paints!"                                        
         @bind-Value="@_paintsUsedStrings.StringValue" />
      
    }

As you can see, we bind to a field variable, and not to the iteration variable. I think this should solve the issue of binding to a collection.

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

1 Comment

It worked! Fantastic explanation as well. It makes sense now that I can't adjust the actual iteration variable, but I can adjust a field of the object. Thanks again for your help.

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.