Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

For loop not returning expected value - C# - Blazor

Using Blazor, I am creating a pagination feature for my project. The main concept is just using linq's .Skip() and .Take(), I will only take the list items for the page clicked from the list.

The code that creates the pagination buttons: (E.G: 1,2,3)

<ul class="pagination float-center">
  @for (int i = 0; i < Math.Ceiling((decimal)articleService.ReturnAll().Count() / numPerPage); i++)
    {
      <li class="page-item"><a class="page-link" onclick="@(() => ReturnPage(i))">@i</a></li>
    }
</ul>

I'm fine withing using 0 indexing here for my pagination.

This above code creates the buttons that when pressed (say page 1 which is the 2nd page), passes the index of the for loop which I will later multiply by the amount per page, to get the amount of elements in the list to skip.

For example when clicking page 1, I will need to skip 2 elements in the list, then take the next 2. (Assuming I want 2 items as the amount per page)

Then my ReturnPage function will skip the current page (whats clicked) - 1, then multiply by 2 (or amount per page) to find the total amount to skip. If the user clicks 0 (first page) then I need to .Skip(0) and just .Take(amount per page).

void ReturnPage(int i)
 {

    articles = articleService.ReturnAll()
                                .OrderByDescending(x => x.LastUpdated)
                                    .Skip((i == 0) ? 0 : (i - 1) == 0 ? numPerPage : (i - 1) * numPerPage)
                                        .Take(numPerPage)
                                            .ToList();
 }

Putting this into context if I have a list (articles) with a total count of items at 3. This will return me pagination buttons of 0,1. page 0 will show 2 items, and page 1 will show 1 item.

If I click pagination button 1, I should pass 1 (i) to the ReturnPage method and that will calculate a skip amount of 2 items. Meaning this page will skip the first 2 items in the list, then take the next 2. (just 1 item in this case)

If I click back to pagination button 0, I should pass an i value of 0, skipping nothing, and just take the first 2 items.

However I am not seeing the correct (i) value being passed into the ReturnPage function at all.

Running the same example I outlined above, the correct amount of buttons are returned by the for loop: Pagination Buttons

But when debugging, i has a value of 2 (everytime?). Which throws off the whole .Skip() functionality.

Wrong Expected Value

My interpretation is, completely disregarding the linq stuff, something in the for loop is wrong. The condition seems correct to me. If I have a count of 3 and 2 per page, which is 1.5 which would mean 2 pages. So my i values should be 0 and 1, but somehow its 2?

I must be missing something fundamental here, any ideas?

like image 454
Night Channels Avatar asked Feb 21 '19 16:02

Night Channels


People also ask

Can a for loop return a value in C?

The answer is yes, it will return.

Can you return a value from a for loop?

You cannot return a value from a for loop in java. Only methods have the privilege of returning values. for loop is a control flow statement whose purpose is to iterate through the number of times till the condition is true. While iterating, you can define statements which needs to be executed.

Can we use return in for loop C#?

You cannot use return statement in place of break statement. But inside a function, the for loop can be escaped with return statement.

How do you return a value from a while loop in C#?

The return Keyword With while LoopC# return statement will exit the current method even if used in a while loop. Normally, you'd use a break statement to exit the loop instead.


1 Answers

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.

like image 192
enet Avatar answered Oct 19 '22 14:10

enet