Base solution for your next web application
Open Closed

injection of API_BASE_URL for new services to support Kendo #5478


User avatar
0
BobIngham created

aspnet-core, angular; 5.4.1 I have used Kendo grids for many years in my MVC projects and my users love the functionality of the grids for data analysis. To implement similar functionality using the Zero framework results in far too much code for filtering, grouping (I'm not even sure it's possible), export to Excel, PDF etc. Kendo grids use a DataSourceRequest object to carry out the vase majority of this functionality and to this end I have created a new controller in the [projectname].Web.Host project to implement this functionality:

using Abp.Auditing;
using Kendo.Mvc.Extensions;
using Kendo.Mvc.UI;
using Microsoft.AspNetCore.Mvc;
using Nuagecare.NcEntity;
using Nuagecare.Web.Controllers;
using System.Threading.Tasks;

namespace Nuagecare.Web.Host.Controllers
{
    [Produces("application/json")]
    [ApiExplorerSettings(IgnoreApi = true)]
    [DisableAuditing]
    public class KendoController :  NuagecareControllerBase
    {
        private readonly INcEntityAppService _ncEntityAppService;

        public KendoController(INcEntityAppService ncEntityAppService)
        {
            _ncEntityAppService = ncEntityAppService;
        }

        public async Task<ActionResult> GetEntities([DataSourceRequest]DataSourceRequest request)
        {
            var model = await _ncEntityAppService.GetAllForKendoGrid();
            return Json(model.ToDataSourceResult(request));
        }
    }
}

Next I implement a new service in my angular project:

import { Injectable, Inject, Optional, InjectionToken } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { toDataSourceRequestString, translateDataSourceResultGroups, translateAggregateResults, DataResult, DataSourceRequestState } from '@progress/kendo-data-query';
import { GridDataResult } from '@progress/kendo-angular-grid';

import { Observable } from 'rxjs';
import 'rxjs/add/operator/map';

export const API_BASE_URL = new InjectionToken<string>('API_BASE_URL');

@Injectable({
  providedIn: 'root'
})
export class KendoGridService {
  private http: HttpClient;
  private baseUrl: string;

  constructor(@Inject(HttpClient) http: HttpClient, @Optional() @Inject(API_BASE_URL) baseUrl?: string) {
    this.http = http;
    this.baseUrl = baseUrl ? baseUrl : '';
  }

  getEntities(state: DataSourceRequestState): Observable<DataResult> {
    let url_ = this.baseUrl + 'kendo/getentities';
    url_ = url_.replace(/[?&]$/, '');

    const queryStr = `${toDataSourceRequestString(state)}`; // Serialize the state
    const hasGroups = state.group && state.group.length;

    return this.http
      .get(`${url_}?${queryStr}`) // Send the state to the server
      .map(({ data, total/*, aggregateResults*/ }: GridDataResult) => // 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)
        })
      );
  }
}

All is working well except the injection of the API_BASE_URL (copied from the dynamically created service-proxies.ts) results in an empty value.

How do I properly inject API_BASE_URL to a new service?


2 Answer(s)
  • User Avatar
    0
    ryancyq created
    Support Team

    Use

    import { API_BASE_URL } from '@shared/service-proxies/service-proxies';
    

    instead of

    export const API_BASE_URL = new InjectionToken<string>('API_BASE_URL');
    
  • User Avatar
    0
    BobIngham created

    @ryancyq, DOH! Thanks.