All Components

Integration with UI for ASP.NET Core

The UI for ASP.NET Core and UI for ASP.NET MVC suites provide a DataSourceRequest model binder and a ToDataSourceResult() method which process bulk data operations.

This article demonstrates how to use these features in Angular applications by applying the Data Query helper functions. For the full project source, refer to this GitHub repository.

Sample Integration Project

To implement the sample project:

Prerequisites

Setup

  1. Create an ASP.NET Core web application that is integrated with Angular.

    As a starting point, the sample project uses the ASP.NET Core with Angular template approach, which is recommended in the official Angular documentation.

  2. Install Telerik UI for ASP.NET Core. For more information, refer to the article on getting started.

    You can skip the UI-related steps because the sample project uses only DataSourceRequest and ToDataSourceResult() from the Kendo.Mvc.UI and Kendo.Mvc.Extensions namespaces.

  3. Create an endpoint, which will process the requests, by using the DataSourceRequest attribute and a model binder. Perform all data operations by using the ToDataSourceResult() method and return the result as JSON.

    using Microsoft.AspNetCore.Mvc;
    using Angular2Spa.Models;
    using Kendo.Mvc.UI;
    using Kendo.Mvc.Extensions;
    
    namespace Angular2Spa.Controllers
    {
       [Produces("application/json")]
       [Route("api/Products")]
       public class ProductsController : Controller
       {
           private readonly SampleContext _context;
    
           public ProductsController(SampleContext context)
           {
               _context = context;
           }
           // GET: api/Products
           [HttpGet]
           public JsonResult GetProducts([DataSourceRequest]DataSourceRequest request)
           {
               var result = Json(_context.Products.ToDataSourceResult(request));
               return result;
           }
       }
    }
  4. Install the Data Query and Grid packages.

  5. Create an Angular service which will process the requests and parse the response by using the toDataSourceRequestString, translateDataSourceResultGroups, and translateAggregateResults Data Query methods.

    import { Injectable } from '@angular/core';
    import {
        toDataSourceRequestString,
        translateDataSourceResultGroups,
        translateAggregateResults,
        DataResult,
        DataSourceRequestState
    } from '@progress/kendo-data-query';
    import { GridDataResult, DataStateChangeEvent } from '@progress/kendo-angular-grid';
    import { Observable } from 'rxjs';
    import { Http } from '@angular/http';
    import 'rxjs/add/operator/map';
    
    @Injectable()
    export class DataService {
        private BASE_URL: string = 'api/Products';
    
        constructor(private http: Http) { }
    
        public fetch(state: DataSourceRequestState): Observable<DataResult> {
            const queryStr = `${toDataSourceRequestString(state)}`; // Serialize the state
            const hasGroups = state.group && state.group.length;
    
            return this.http
                .get(`${this.BASE_URL}?${queryStr}`) // Send the state to the server
                .map(response => response.json())
                .map(({data, total/*, aggregateResults*/}) => // Process the response
                    (<GridDataResult>{
                        // If there are groups, convert them to a compatible format
                        data: hasGroups ? translateDataSourceResultGroups(data) : data,
                        total: total,
                        // Convert the aggregates if such exist
                        //aggregateResult: translateAggregateResults(aggregateResults)
    
                    })
                )
        }
    }
  6. Bind the Grid to the service.

    import { Component } from '@angular/core';
    import { Http } from '@angular/http';
    import { DataService } from './data.service';
    import { Observable } from 'rxjs';
    import { GridDataResult, DataStateChangeEvent } from '@progress/kendo-angular-grid';
    import { DataSourceRequestState, DataResult } from '@progress/kendo-data-query';
    
    @Component({
       selector: 'fetchdata',
       template: `
       <kendo-grid [data]="products"
           [pageSize]="state.take"
           [skip]="state.skip"
           [sort]="state.sort"
           [sortable]="true"
           [pageable]="true"
           [scrollable]="'scrollable'"
           [groupable]="true"
           [group]="state.group"
           [filterable]="true"
           [filter]="state.filter"
           (dataStateChange)="dataStateChange($event)"
           [height]="370">
    
           <kendo-grid-column field="productId" title="ID" [width]="100" [filter]="'numeric'">
           </kendo-grid-column>
           <kendo-grid-column field="productName" title="Product Name" [width]="320">
           </kendo-grid-column>
           <kendo-grid-column field="unitPrice" title="Unit Price" [width]="120" [filter]="'numeric'">
           </kendo-grid-column>.
           <kendo-grid-column field="unitsInStock" title="Units In Stock" [width]="120" [filter]="'numeric'">
           </kendo-grid-column>
       </kendo-grid>
       `
    })
    export class FetchDataComponent {
       public products: GridDataResult;
       public state: DataSourceRequestState = {
           skip: 0,
           take: 20
       };
    
       constructor(private dataService: DataService) {
           this.dataService.fetch(this.state).subscribe(r => this.products = r);
       }
    
       public dataStateChange(state: DataStateChangeEvent): void {
           this.state = state;
           this.dataService.fetch(state)
               .subscribe(r => this.products = r);
       }
    }
In this article