Closed
Description
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
- Using the latest ASP.NET CORE 3 PREVIEW 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.