Skip to content

Razor components/Blazor doesn't iterate correctly inside a for loop of a List #7134

Closed
@chrdlx

Description

@chrdlx

Describe the bug

I made a simple razor component that just renders a list of strings in buttons. Each button is clickable so when I click one, I add the text "AddedText" to the string inside the button.
This doesn't work since the counter variable always sets to the last position, throwing an out of range exception.
This seems to happen only in the onclick binding, because the list renders correctly in html.

To Reproduce

  1. Using the latest ASP.NET CORE 3 PREVIEW 2
  2. Run this code (this is just a modified Counter.cshtml from the template)
@page "/counter"
@for (int c=0;c<stringlist.Count;c++)
{
    <button onclick=@(()=>addText(c))>
        @stringlist[c]
    </button>
}
@functions {
    List<string> stringlist = new List<string>();

    void addText(int index)
    {
        stringlist[index] += "AddedText";
    }

    protected override void OnInit()
    {
        stringlist.Add("STRING1");
        stringlist.Add("STRING2");
        stringlist.Add("STRING3");
        base.OnInit();
    }
}

Expected behavior

I expected the button when clicked, to change the string in the correct position of the List.

FIX

To circumvent this issue, I've found that if I use an intermediate counter variable in the FOR LOOP it works, so here's the FOR LOOP change:

@for (int c=0;c<stringlist.Count;c++)
{
    int c2 = c; //Intermediate counter
    <button onclick=@(()=>addText(c2))>
        @stringlist[c2]
    </button>
}

This way the loop not only renders correctly, but reacts correctly to the click event modifying the string in the List.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-mvcIncludes: MVC, Actions and Controllers, Localization, CORS, most templates

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions