Angular Data Grid - how to POST grid state to WEB API endpoint?

2 Answers 159 Views
Grid
Bob
Top achievements
Rank 1
Iron
Bob asked on 20 Jun 2022, 01:44 PM
Hi, I'm attempting to post a grid's state (filters/paging/sorting/etc) from the Kendo Angular grid to a .NET Core Web Api endpoint.  The reason I've been asked to try to do this as we are building custom filters that could possibly be long enough to cause URL truncation if we pass in querystring.

Is there a way to post the grid state like below?  If so, does anyone have sample Angular code showing how to send over a request body that the back-end can transform to DataSourceRequest object and correctly apply grid state (filters/paging/sorting/etc)? My brief attempts at this have failed so far.
public DataSourceResult TestEndpoint([DataSourceRequest] DataSourceRequest request)
{
    IEnumerable<Object> myData = null;
    return myData.ToDataSourceResult(request);
}

2 Answers, 1 is accepted

Sort by
0
Bob
Top achievements
Rank 1
Iron
answered on 22 Jun 2022, 06:19 PM | edited on 22 Jun 2022, 06:19 PM
I ended up solving by making a new class in API to translate the Angular DataSourceRequestState object to the C# DataSourceRequest object.  This doesn't take into account grouping and aggregates.  If anyone has any better answers, I'm not super attached to this :)

Kendo reference: https://www.telerik.com/kendo-angular-ui/components/data-query/api/toDataSourceRequest/

Sample API endpoint:
    [HttpPost]
    public DataSourceResult TestEndpoint([FromBody] DataSourceRequestState request)
    {
        IEnumerable<Object> myData = null;
        return myData.ToDataSourceResult(request);
    }

New class:
using Kendo.Mvc;
using Kendo.Mvc.Infrastructure;
using Kendo.Mvc.UI;

namespace eBlu.BenefitCallsheet.Api.Models;

/// <summary>
///     Auto-translate Angular DataSourceRequestState to C# DataSourceRequest
/// </summary>
public class DataSourceRequestState : DataSourceRequest
{
    private string _filter;

    private string _sort;

    public int Size
    {
        get => PageSize;
        set => PageSize = value;
    }

    public string Filter
    {
        get => _filter;
        set
        {
            _filter = value;
            // sourced from: Kendo.Mvc.UI.DataSourceRequestModelBinder
            Filters = FilterDescriptorFactory.Create(value);
        }
    }

    public string Sort
    {
        get => _sort;
        set
        {
            _sort = value;
            // sourced from: Kendo.Mvc.UI.DataSourceRequestModelBinder
            Sorts = DataSourceDescriptorSerializer.Deserialize<SortDescriptor>(value);
        }
    }
}

0
Svet
Telerik team
answered on 23 Jun 2022, 06:55 AM

Hi Bob,

I can confirm that the overtaken approach seems valid.

I can further add that a POST request can be used instead of a GET. For this purpose, use the toDataSourceRequestString() function and pass the created string to the body parameter of the POST method. In order for the current state of the grid to be picked up by the model binder correctly, add the following headers to the POST request:

const httpOptions = {
            headers: new HttpHeaders({
                'Content-Type': 'application/x-www-form-urlencoded'
            })
        };

 

The essential parts are the following:

 

public fetch(dataItem?: any, action: string = ''): Observable<any> {

        switch (action) {
          case '': {
            const queryStr = `${toDataSourceRequestString(this.state)}`;
            const hasGroups = this.state.group && this.state.group.length;

            const httpOptions = {
              headers: new HttpHeaders({
                'Content-Type': 'application/x-www-form-urlencoded'
              })
            }

            return this.http.post('api/postBlogs', queryStr, httpOptions).pipe(
                    // Process the response
              map(({ data, total }: GridDataResult): GridDataResult => {
                        return {
                            data: hasGroups ? translateDataSourceResultGroups(data) : data,
                            total: total
                        };
                    }
                    ));
            }

 

this is the controller:

 

        [Route("api/postBlogs")]
        [HttpPost]
        
        public JsonResult PostProducts([DataSourceRequest] DataSourceRequest request)
        {

            var result = Json(this._context.Blog.ToList().ToDataSourceResult(request));            
            
            return result;
        }

I hope this helps.

Regards,
Svet
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Tags
Grid
Asked by
Bob
Top achievements
Rank 1
Iron
Answers by
Bob
Top achievements
Rank 1
Iron
Svet
Telerik team
Share this question
or