Base solution for your next web application
Open Closed

Asp.Net Core null response results as an empty object in Angular instead of null #7789


User avatar
0
abarref created

--- Asp Net Zero version: 7.2.3 ---

I'm using the proxies generated by NSwag to call the backend like:

_entityProxyService.getSomeDto(id).subscribe(r =>{
    this.someDto = r; <------- here I'm expecting to possibly receive a null value
});

where getSomeDto(id) would be:

    public Task<SomeDto> GetSomeDto(int id)
    {
        return _dbContext.Entities.Where(m => m.Id ==id).Select(m => new SomeDto()
        {
            Id = mId
        }).FirstOrDefaultAsync();
    }

FirstOrDefaultAsync could return one result or null, but when it returns null I'm getting an empty javascript object on the other side, instead of simple null.

Is there a way to receive null backend responses as null javascript values?


5 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team

    I did some research and there seems to be no way.

  • User Avatar
    0
    abarref created

    Hi @maliming, thanks for your reply.

    I found a workaround that implies transforming the nswag proxy response:

    service.config.nswag file:

      "extensionCode": "service.extensions.ts",
      "clientBaseClass": "ClientBase",
      "useTransformOptionsMethod": true,
      "useTransformResultMethod": true,
      
    

    service.extenisons.ts file:

    ...... UPDATED: please view the other answer below
    
    

    It's not a clean solution but achieves the desired behaviour.

  • User Avatar
    0
    daws created

    We have the same issue on our code. We just migrated from abpzero 6.4 (where null was translated to null) to 7.2.3 (where null is translated to an empty javascript object)

    Your solution @abarref doesn't compile for us : Property 'pipe' doesn't exist on type 'U'
    observable = observable.pipe(map((data) => {

    Any suggestion ?

  • User Avatar
    1
    abarref created

    Sorry, I ommitted some lines that I thought were not required. This is my full service.extensions.ts:

    import {map} from 'rxjs/operators';
    
    export class ClientBase {
        protected transformOptions(options: any) {
            // Change options if required
    
            // console.log('HTTP call, options: ' + JSON.stringify(options));
            //
            // options.headers.append("myheader", "myvalue");
    
            // if (options != null) {
            //     options.isServiceProxyRequest = true;
            // }
    
            // options.responseType = 'json';
    
            // @ts-ignore
            return Promise.resolve(options);
        }
    
        protected transformResult<R, U>(url: string, response: R, processor: (response: R) => U) {
            let observable = processor(response);
    
            // @ts-ignore
            observable = observable.pipe(map((data) => {
                return this.isEmptyObject(data) ? null : data;
            }));
    
            return observable;
        }
    
        // Reference: https://stackoverflow.com/a/32108184/1454888
        isEmptyObject(obj) {
            if (obj == null) {
                return true;
            }
    
            if (obj.constructor === Array || obj.constructor === ArrayBuffer) {
                return false;
            }
    
            for (let prop in obj) {
                if (obj.hasOwnProperty(prop)) {
                    return false;
                }
            }
    
            return JSON.stringify(obj) === JSON.stringify({});
        }
    }
    
    

    So to avoid those compilation issues I added // @ts-ignore on top of them

  • User Avatar
    0
    daws created

    Works fine. Thanks !