gustavnavar / Grid.Blazor

Grid component with CRUD for Blazor (client-side and server-side) and ASP.NET Core MVC
GNU Lesser General Public License v2.1
696 stars 134 forks source link

How to sort the grid using an API rest as a data source #392

Closed andresfranco closed 10 months ago

andresfranco commented 1 year ago

I am trying to understand how to implement the Grid in my project . The data is fetched from a REST API (both projects are using .netcore 7). Although the grid populates successfully when I run my project, I'm facing an issue with the sorting functionality.

When I click on a column to sort, it seems to execute the same initial query used to populate the grid. As a result, the sorting feature doesn't work as expected. I've checked the debug output in Visual Studio but haven't been able to identify what might be causing the problem.

Could someone please guide me on how to properly set up the sorting functionality with Grid.Blazor? Any help or suggestions would be greatly appreciated.

This is my Blazor component code :

@using GridShared
@using GridShared.Sorting;
@using GridShared.Utility
@using Microsoft.Extensions.Primitives
@inject NavigationManager NavigationManager
@inject HttpClient HttpClient;

<h3>Movies Grid</h3>

@if (_task.IsCompleted)
{
    <GridComponent T="Movie" Grid="@_grid">

    </GridComponent>
}
else
{
    <p><em>Loading...</em></p>
}

@code {
    public class Movie
    {
        public Guid MovieId { get; set; }
        public string MovieName { get; set; } = String.Empty;
        public decimal RentalCost { get; set; }
        public int RentalDuration { get; set; }

        public Movie(Guid movieId, string movieName, decimal rentalCost, int rentalDuration)
        {
            MovieId = movieId;
            MovieName = movieName;
            RentalCost = rentalCost;
            RentalDuration = rentalDuration;
        }
    }

    private CGrid<Movie> _grid;
    private Task _task;

    public static Action<IGridColumnCollection<Movie>> Columns = c =>
    {
        c.Add(o => o.MovieName).Sortable(true);

        c.Add(o => o.RentalCost).Sortable(true);
        c.Add(o => o.RentalDuration).Sortable(true);

    };

    protected override async Task OnParametersSetAsync()
    {
        try
        {
            string url = "https://localhost:7227/api/Movies";
            var queryParams = new Dictionary<string, string> {{"page", "2"}};
            var query = new QueryDictionary<StringValues>();
            foreach (var kvp in queryParams)
            {
                query.Add(kvp.Key, new StringValues(kvp.Value));
            }

            var client = new GridClient<Movie>(HttpClient, url, query, false, "moviesGrid", Columns)
           .Filterable()
           .Sortable()
           .WithMultipleFilters()
           .Searchable();

      _grid = client.Grid;
      _task = client.UpdateGrid();
      await _task;
    }
    catch (Exception e)
    {
      Console.WriteLine(e.Message);
    }
  }

This is This is my API Rest controller method:

 [HttpGet]
        public ActionResult<List<Movie>> Get()
        {
            var movies = _service.GetAllMovies();
            var server = new GridServer<Movie>(movies, Request.Query,
                  true, "moviesGrid").Sortable()
            .Filterable()
            .WithMultipleFilters()
            .Searchable();
            return Ok(server.ItemsToDisplay);
           ;
        }
gustavnavar commented 1 year ago

You are not using the column definition on the server side. If your grid component name is Movies.razor:

    [HttpGet]
    public ActionResult<List<Movie>> Get()
    {
        var movies = _service.GetAllMovies();
        var server = new GridServer<Movie>(movies, Request.Query, true, "moviesGrid", Movies.Columns)
             .Sortable()
            .Filterable()
            .WithMultipleFilters()
            .Searchable();

        return Ok(server.ItemsToDisplay);
    }

I think this is the source of your error.

On the other side you don't need this code on the client side:

var queryParams = new Dictionary<string, string> {{"page", "2"}};
            var query = new QueryDictionary<StringValues>();
            foreach (var kvp in queryParams)
            {
                query.Add(kvp.Key, new StringValues(kvp.Value));
            }