For Loop Not Returning Expected Value - C# - Blazor

For loop not returning expected value - C# - Blazor

Your for loop should contain a local variable like this:

 @for (int i = 0; i < Math.Ceiling((decimal)articleService.ReturnAll().Count() / numPerPage); i++)
{
var localVariable = i;

<li class="page-item"><a class="page-link" onclick="@(() => ReturnPage(localVariable ))">@i</a></li>
}

This is standard C# behavior where lambda expression @(() => ReturnPage(localVariable )) has access to a variable and not to the value of the variable. You have to define a variable which is local to the for loop, otherwise your lambda expression will always call ReturnPage(i) and i equals Math.Ceiling((decimal)articleService.ReturnAll().Count() at the end of the loop.

Why does @for loop does not work in Razor and Blazor?

Take a look at the following code (a simpler version of your code in my index.razor)

@page "/"

<h1>Hello, world!</h1>

Welcome to your new app.

<SurveyPrompt Title="How is Blazor working for you?" />

@for (int i = 0; i < 3; i++)
{
<button class="btn btn-primary mr-2" @onclick="(() => ButtonClick(i))">@($"Button {i}") </button>
}
<h4>Value = @value</h4>

@code {

int value = -1;

void ButtonClick(int x)
=> value = x;
}

Your expectation is that Value will display 1 when you click on Button 1. Not so, it always displays 3, the final value of i. The button click event submits the value of i when the button is clicked, the loop has long completed.

In your code i is 3 - the last version of i that stopped the for loop. - and m in style1[m] is 3 pointing to a none existent 4th member of style1. Index was out of range is quite correct, but quite as informative as it could be.

Sometimes you can't see the wood for the trees!!

How to change a variable declared inside a loop?

As theBool is captured by the lambda, I expected it still exists after le loop.

That is true...

@PanagiotisKanavos : Do you mean that Blazor only subscribe for Ui refresh on fields and not variables ?

Each time you click on an anchor element, the StateHasChanged method is automatically called by the framework, and the UI is re-rendered, but you can't see it changed, as at the start of the loop you've got var theBool = false;
And thus, <span>For @item, theBool is @theBool</span> is re-rendered to:

<span>For item2, theBool is false</span>

if you've clicked on the second item.

Your code will never work as at each iteration of the loop the local variable theBool is set to false; that is you can't see the changes on the UI...

You can solve it like this:

<ul>
@foreach (var item in Items)
{

<li>
<span>For @item.Name, item.IsSelected is @item.IsSelected</span>

(<a href="" @onclick="@(e => { item.IsSelected = !item.IsSelected; })">Reverse bool for @item.Name</a>)
</li>
}
</ul>

@code {

private List<Item> Items = Enumerable.Range(1, 5).Select(i => new Item { Name = $"item{i}" }).ToList();

public class Item
{
public string Name { get; set; }
public bool IsSelected { get; set; }
}
}

Copy and test...

Why doesn't the binding work with an array and a for loop in my example (blazor)?

You need to create another variable inside the loop for getting the correct variable

@for (var i = 0; i < 3; i++)
{
var ii = i;
<input type="text" @bind="TraineeValues[ii]" />
}

Blazor How to use a bind to an array of booleans

Somewhere in your code (you do not display all your code ) the 'delegate' EventCallback is executed, but the 'Index was outside the bounds of the array"; This occurs because the code that accesses the Index value always gets the last Index + 1

To solve this, use a local variable to which you should assigned the value of i, something like this"

var local = i;

See my answer here...

Hope this helps...



Related Topics



Leave a reply



Submit