Angular - cli proxy generation error on GET request with nested Dto
Abp version
4.4.0 UI: Angular DB: MSSQL
Reproduce
I have a module with an AppService which is not related to abp entities or abp dtos (like EntityDto). This service is just used to expose endpoints that call a custom class (ITransientDependency) that I use as a repository (injecting Dbcontext) to run raw sql.
AppService
[Authorize]
public class CustomAppService : ApplicationService
{
// .... inject repo
public async Task<IEnumerable<OutPutDto>> GetRecordsAsync(InputDto filter)
{
var dtos = await _repo.GetRecords(filter);
return dtos;
}
}
Repository
public class CustomRepository : ICustomRepository, ITransientDependency
{
// .... inject DbContext
public async Task<List<OutputDto>> GetRecords(InputDto filter)
{
var result = // .... raw sql (linq), using filter data
return await result.ToListAsync();
}
}
InputDto (Nested)
public class InputDto
{
public OperationDto FirstOperation{ get; set; }
public OperationDto SecondOperation { get; set; }
}
public class OperationDto
{
public string Operator { get; set; }
public List<string> Values { get; set; }
}
The issue
When I run:
abp generate-proxy -m module-name
in angular root folder, i generate the proxies folder and everything ok except for this detail:
import type { ..... } from './models';
import { RestService } from '@abp/ng.core';
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class CustomService {
apiName = 'Default';
getRecord = (filter: InputDto) =>
this.restService.request<any, outputDto>({
method: 'GET',
url: '/api/module-name/custom/record',
params: {
// ERROR HERE, Property 'firstOperation_Operator' does not exist on type 'InputDto'
firstOperation_Operator: filter.firstOperation_Operator,
firstOperation_Values: filter.firstOperation_Values, // ERROR HERE
secondOperation_Operator: filter.secondOperation_Operator, // ERROR HERE
secondOperation_Values: filter.secondOperation_Values // ERROR HERE
},
},
{ apiName: this.apiName });
constructor(private restService: RestService) {}
}
I think It should be:
firstOperation_Operator: filter.firstOperation.operator,
Please Help!
Hi @nev-21
Can the share the generate-proxy.json so that we can find the source of the problem.
Hi @mehmet-erim, yes of course, I deleted the parts that are not necessary.
{
"generated": [
"app",
"module"
],
"modules": {
"module": {
"rootPath": "module",
"remoteServiceName": "Default",
"controllers": {
"Company.Module.CustomReport.CustomAppService": {
"controllerName": "Custom",
"type": "Company.Module.CustomReport.CustomAppService",
"interfaces": [
{
"type": "Volo.Abp.Validation.IValidationEnabled"
},
{
"type": "Volo.Abp.Auditing.IAuditingEnabled"
},
{
"type": "Volo.Abp.GlobalFeatures.IGlobalFeatureCheckingEnabled"
}
],
"actions": {
"GetRecordsAsyncByFilter": {
"uniqueName": "GetRecordsAsyncByFilter",
"name": "GetRecordsAsync",
"httpMethod": "GET",
"url": "api/module/custom/records",
"supportedVersions": [],
"parametersOnMethod": [
{
"name": "filter",
"typeAsString": "Company.Module.CustomReport.InputDto, Company.Module.Domain",
"type": "Company.Module.CustomReport.InputDto",
"typeSimple": "Company.Module.CustomReport.InputDto",
"isOptional": false,
"defaultValue": null
}
],
"parameters": [
{
"nameOnMethod": "filter",
"name": "FirstOperation.Operator",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "filter"
},
{
"nameOnMethod": "filter",
"name": "FirstOperation.Values",
"jsonName": null,
"type": "System.Collections.Generic.List<System.String>",
"typeSimple": "[string]",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "filter"
},
{
"nameOnMethod": "filter",
"name": "SecondOperation.Operator",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "filter"
},
{
"nameOnMethod": "filter",
"name": "SecondOperation.Values",
"jsonName": null,
"type": "System.Collections.Generic.List<System.String>",
"typeSimple": "[string]",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "filter"
}
],
"returnValue": {
"type": "System.Collections.Generic.IEnumerable<Company.Module.CustomReport.OutputDto>",
"typeSimple": "[Company.Module.CustomReport.OutputDto]"
},
"allowAnonymous": false
}
}
}
}
}
},
"types": {
"Company.Module.CustomReport.InputDto": {
"baseType": null,
"isEnum": false,
"enumNames": null,
"enumValues": null,
"genericArguments": null,
"properties": [
{
"name": "FirstOperation",
"jsonName": null,
"type": "Company.Module.CustomReport.OperationDto",
"typeSimple": "Company.Module.CustomReport.OperationDto",
"isRequired": false
},
{
"name": "SecondOperation",
"jsonName": null,
"type": "Company.Module.CustomReport.OperationDto",
"typeSimple": "Company.Module.CustomReport.OperationDto",
"isRequired": false
}
]
},
"Company.Module.CustomReport.OperationDto": {
"baseType": null,
"isEnum": false,
"enumNames": null,
"enumValues": null,
"genericArguments": null,
"properties": [
{
"name": "Operator",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
"isRequired": false
},
{
"name": "Values",
"jsonName": null,
"type": "[System.String]",
"typeSimple": "[string]",
"isRequired": false
}
]
},
"Company.Module.CustomReport.OutputDto": {
"baseType": null,
"isEnum": false,
"enumNames": null,
"enumValues": null,
"genericArguments": null,
"properties": [
{
"name": "Nombre",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
"isRequired": false
}
]
}
}
}
Hi @nev-21,
Can you replace the getRecord method with the following:
getRecord = (filter: InputDto) =>
this.restService.request<any, outputDto>({
method: 'GET',
url: '/api/module-name/custom/record',
params: {
['FirstOperation.Operator']: filter.firstOperation.operator,
['FirstOperation.Values']: filter.firstOperation.values,
['SecondOperation.Operator']: filter.secondOperation.operator,
['SecondOperation.Values']: filter.secondOperation.values
},
},
{ apiName: this.apiName });
If the errors disappear that way, please let us know.
Hi, @mehmet-erim I replaced and it works, the errors disappeared. Also, I tested it with a debug break-point in the baking api service, and it works, the Input Dto was sent correctly.
We will handle that case on the ABP schematics to fix the problem. Thanks for the reporting!
Thanks @mehmet-erim