Hello support,
We are implementing a "Gird" containing a "ChildGrid". We are using the Javascript Syncfusion controls. The data for the parent and child grids should be retrieved from a ASP.NET Core Web API (REST). In this case we are only trying to display information so no editing (hence we are only making GET requests to fetch the data).
The problem occurs when trying to fetch the data for the child grid. When debugging I get a breakpoint in the correct action, however I don't get the parameters on which to filter. Here is my code:
Client code (TypeScript):
class CustomerService { private content: HTMLElement; private grid: ej.Grid; constructor(content: HTMLElement) { this.content = content; } initGrid() { const customerDataManager = new ej.DataManager({ url: "api/Customers", adaptor: new ej.WebApiAdaptor() }); const subscriptionDataManager = new ej.DataManager({ url: "api/Subscriptions", adaptor: new ej.WebApiAdaptor() }); this.grid = new ej.Grid(this.content, { dataSource: customerDataManager, childGrid: { dataSource: subscriptionDataManager, queryString: "tenantId", columns: [ { field: "id", headerText: "Subscription ID" } ] }, allowFiltering: true, allowSorting: true, columns: [ { field: "id", headerText: "Klant Tenant", isPrimaryKey: true, visible: true }, { field: "companyName", headerText: "Naam" }, { field: "tenantId", headerText: "Tenant" } ] }); } } |
[HttpGet, Route("api/Customers")] public async Task<object> Customers() { var customers = await _customerService .GetCustomersAsync(); return new { result = customers, count = customers.Count }; } [HttpGet, Route("api/Subscriptions")] public async Task<object> Subscriptions(string tenantId) { var subscriptions = await _subscriptionService .GetSubscriptionsForCustomerAsync(tenantId); return new {result = subscriptions, count = subscriptions.Count}; } |
//Grid
initGrid() {
const customerDataManager = new ej.DataManager({
url: "api/Customers",
adaptor: new ej.UrlAdaptor()
});
const subscriptionDataManager = new ej.DataManager({
url: "api/Subscriptions",
adaptor: new ej.UrlAdaptor()
});
. . .
});
}
}
//Controller
// create a Filtering class which has properties of Grid where query
public class Filter
{
public string condition { get; set; }
public string field { get; set; }
public string @operator { get; set; }
public bool ignoreCase { get; set; }
public bool isComplex { get; set; }
public List<Filter> predicates { get; set; }
public object value { get; set; }
}
// here we can pass the paremeter
[HttpGet, Route("api/Subscriptions")]
public async Task<object> Subscriptions(int skip, int take, List<Filter> where)
{
//we can get the child query string filter value from filter parameters
// for paging we can also get the skip and take value from ski and take paramete
// Code something
return new { result = subscriptions, count = subscriptions.Count };
}
|
/// <reference path="../tsfiles/jquery.d.ts" /> /// <reference path="../tsfiles/ej.web.all.d.ts" /> class CustomerService { private content: HTMLElement; private grid: ej.Grid; constructor(content: HTMLElement) { this.content = content; } initGrid() { const customerDataManager = new ej.DataManager({ url: "api/Customers", adaptor: new ej.UrlAdaptor() }); const subscriptionDataManager = new ej.DataManager({ url: "api/Subscriptions", adaptor: new ej.UrlAdaptor() }); this.grid = new ej.Grid(this.content, { dataSource: customerDataManager, childGrid: { dataSource: subscriptionDataManager, queryString: "tenantId", columns: [ { field: "id", headerText: "Subscription ID" } ] }, allowFiltering: true, allowSorting: true, columns: [ { field: "id", headerText: "Klant Tenant", isPrimaryKey: true, visible: true }, { field: "companyName", headerText: "Naam" }, { field: "tenantId", headerText: "Tenant" } ] }); } } |
[HttpGet, Route("api/Customers")] public async Task<object> Customers(int skip, int take, List<Filter> filters) { var customers = await _customerService .GetCustomersAsync(); return new { result = customers, count = customers.Count }; } [HttpGet, Route("api/Subscriptions")] public async Task<object> Subscriptions(int skip, int take, List<Filter> filters) { var tenantId = dm.Where.SingleOrDefault(f => f.Field == "tenantId").value.ToString(); var subscriptions = await _subscriptionService .GetSubscriptionsForCustomerAsync(tenantId); return new { result = subscriptions, count = subscriptions.Count }; } |
"We have checked the provided code and found that you are using WebApiAdaptor in your application. And also you are returned the data as result and count. This is not a recommended way to return the data when using webApiAdaptor. Please refer to the below Help document for more information about wepApi data adaptor,
Help document: https://help.syncfusion.com/aspnetmvc/grid/data-adaptors#webapi-adaptor "
new { result = customers, count = customers.Count }; |
new { Items = customers, Count = customers.Count }; |
//Grid
initGrid() {
const customerDataManager = new ej.DataManager({
url: "api/Customers",
adaptor: new ej.UrlAdaptor()
});
const subscriptionDataManager = new ej.DataManager({
url: "api/Subscriptions",
adaptor: new ej.UrlAdaptor()
});
. . .
});
}
}
//Controller
// create a Filtering class which has properties of Grid where query
public class Filter
{
public string condition { get; set; }
public string field { get; set; }
public string @operator { get; set; }
public bool ignoreCase { get; set; }
public bool isComplex { get; set; }
public List<Filter> predicates { get; set; }
public object value { get; set; }
}
// here we can pass the paremeter
[HttpPost, Route("api/Subscriptions")]
public async Task<object> Subscriptions(int skip, int take,List<Filter> where)
{
//we can get the child query string filter value from filter parameters
// for paging we can also get the skip and take value from ski and take paramete
// Code something
return new { result = subscriptions, count = subscriptions.Count };
}
|
new { result = customers, count = customers.Count }; |
new { Items = customers, Count = customers.Count }; |
When I convert the return type (while using the "WebApiAdaptor") from:to:
new { result = customers, count = customers.Count }; The grid doesn't display any records.
new { Items = customers, Count = customers.Count };
Here is the error I get in the Javascript console:
Uncaught TypeError: Cannot read property '0' of undefined(…)
addInitTemplate @ ej.web.all.min.js:10
_initGridRender @ ej.web.all.min.js:10
(anonymous function) @ ej.web.all.min.js:10
(anonymous function) @ ej.web.all.min.js:10
fire @ jquery.js:3182
fireWith @ jquery.js:3312
(anonymous function) @ ej.web.all.min.js:10
(anonymous function) @ ej.web.all.min.js:10
(anonymous function) @ ej.web.all.min.js:10
fire @ jquery.js:3182
fireWith @ jquery.js:3312
done @ jquery.js:8754
(anonymous function) @ jquery.js:9120
And this is the JSON response which is returned from the server:
{ "items": [ { "id": "5c4f27f7-9e61-458e-8c34-010e07f68abe", "companyProfile": { "tenantId": "5c4f27f7-9e61-458e-8c34-010e07f68abe", "domain": "aircraftdocking.onmicrosoft.com", "companyName": "NIJL Aircraftdocking" }, "relationshipToPartner": "reseller" }, { "id": "722b5aec-05cf-4bc8-914c-964734f460a4", "companyProfile": { "tenantId": "722b5aec-05cf-4bc8-914c-964734f460a4", "domain": "axendo.onmicrosoft.com", "companyName": "Axendo" }, "relationshipToPartner": "reseller" } ], "count": 2 } |
[HttpGet, Route("api/Customers")] public async Task<object> Customers() { var customers = await _customerService .GetCustomersAsync(); return new { Items = customers, Count = customers.Count }; } |
[HttpGet, Route("api/Customers")]
public async Task<object> Customers()
{
var customers = await _customerService
.GetCustomersAsync();
return new { Items = customers, Count = customers.Count };
}
|