File

libs/ngx-pfe/pfe-service-activator/mapper/mapper.service.ts

Index

Properties
Methods

Methods

Public mapResponseToState
mapResponseToState(response: HttpResponse<UnknownObject> | HttpErrorResponse, config: ServiceActivatorDataMapping[], options?: PfeResponseToStateMapperOptions)
Parameters :
Name Type Optional
response HttpResponse<UnknownObject> | HttpErrorResponse No
config ServiceActivatorDataMapping[] No
options PfeResponseToStateMapperOptions Yes
Returns : void
Public mapStateToRequest
mapStateToRequest(requestDataMapping: ServiceActivatorDataMappingForRequesting[])
Parameters :
Name Type Optional
requestDataMapping ServiceActivatorDataMappingForRequesting[] No

Properties

Readonly conditionsService
Default value : inject(PfeConditionsService)
Readonly getValueService
Default value : inject(PfeServiceActivatorGetValueService)
Readonly logger
Default value : inject(NgxLoggerService)
Readonly stateService
Default value : inject(PfeStateService)
import { inject, Injectable } from '@angular/core';
import { PfeConditionsService } from '../../pfe-conditions/public-api';
import { PfeStateService } from '../../services/pfe-state-service/state.service';
import jsonpath from 'jsonpath';
import { NgxLoggerService } from '@allianz/ngx-logger';
import { PfeServiceActivatorGetValueService } from '../get-value/get-value.service';
import { HttpParamsOptionsFromObject } from '../service/service-activator.model';
import { PfeResponseToStateMapperOptions, ServiceActivatorDataMapping, ServiceActivatorDataMappingForRequesting } from './mapper.model';
import { HttpErrorResponse, HttpResponse } from '@angular/common/http';
import { UnknownObject } from '../../models/unknown-object.model';

@Injectable()
export class PfeServiceActivatorMapperService {
  readonly conditionsService = inject(PfeConditionsService);
  readonly stateService = inject(PfeStateService);
  readonly logger = inject(NgxLoggerService);
  readonly getValueService = inject(PfeServiceActivatorGetValueService);

  public mapStateToRequest(requestDataMapping: ServiceActivatorDataMappingForRequesting[]): HttpParamsOptionsFromObject | undefined {
    const fullState = this.stateService.getFullState();

    let payload = {};
    let uglyWorkaroundFirst = true;

    requestDataMapping.forEach((requestDataMapping) => {
      // If we have conditions and are not fulfilled, we don't add this request param
      if (requestDataMapping.conditions && !this.conditionsService.evaluateConditions(requestDataMapping.conditions, fullState)) {
        return;
      }
      try {
        const storeValue = this.getValueService.getValueByExpression(fullState, requestDataMapping.stateKeyExpression);
        const payloadValue = this.getValueService.getValueByExpression(payload, requestDataMapping.requestDataExpression);

        /**
         * BEGIN - Ugly workaround because JSONPath does not work when we are replacing the root object ("$")
         *         Read more about the issue here: https://github.com/dchester/jsonpath/issues/72
         */
        if (requestDataMapping.requestDataExpression === '$') {
          // Clone stateValue locally
          if (uglyWorkaroundFirst) {
            payload = JSON.parse(JSON.stringify(storeValue));
            uglyWorkaroundFirst = false;
            return;
          }

          if (!uglyWorkaroundFirst && Array.isArray(payloadValue)) {
            payload = [...payloadValue, ...(storeValue as unknown[])];
            return;
          }

          if (!uglyWorkaroundFirst && typeof payloadValue === 'object') {
            payload = { ...payloadValue, ...(storeValue as object) };
            return;
          }
        }
        /* END of Ugly workaround */

        // Remove value from from payload if stateKeyExpression is undefined
        if (storeValue === 'undefined') {
          jsonpath.value(payload, requestDataMapping.requestDataExpression, undefined);
          return;
        }

        // Extend the Array
        if (Array.isArray(payloadValue)) {
          jsonpath.value(payload, requestDataMapping.requestDataExpression, [...payloadValue, ...(storeValue as unknown[])]);
          return;
        }

        // Extend the Object
        if (payloadValue && typeof payloadValue === 'object' && storeValue && typeof storeValue === 'object') {
          jsonpath.value(payload, requestDataMapping.requestDataExpression, { ...payloadValue, ...(storeValue as object) });
          return;
        }

        // Replace string or integer into
        jsonpath.value(payload, requestDataMapping.requestDataExpression, storeValue);
      } catch (error) {
        this.logger.errorToServer('handleServiceActivatorRequest: Error in requestDataMapping ', error);
      }
    });

    return payload;
  }

  public mapResponseToState(
    response: HttpResponse<UnknownObject> | HttpErrorResponse,
    config: ServiceActivatorDataMapping[],
    options?: PfeResponseToStateMapperOptions
  ): void {
    config.forEach((responseDataMapping) => {
      const fullState = this.stateService.getFullState();
      // If we have conditions and are not fulfilled, we don't execute the mapping for this object
      if (responseDataMapping.conditions && !this.conditionsService.evaluateConditions(responseDataMapping.conditions, fullState)) {
        return;
      }
      try {
        const responseBody = response instanceof HttpErrorResponse ? response.error : response.body;

        const responseData = responseDataMapping.useHTTPResponseAsData ? response : responseBody;

        // Same issue as in the requestMapping: https://github.com/dchester/jsonpath/issues/72
        if (responseDataMapping.stateKeyExpression === '$') {
          let state = this.stateService.getFullState();
          if (typeof responseData === 'object') {
            state = { ...state, ...responseData };
          } else {
            this.logger.error('The responseDataExpression "$" can only be used with objects in the responseData');
          }
          this.stateService.setFullState(state);
        } else {
          if (responseData) {
            const value = this.getValueService.getValueByExpression(responseData, responseDataMapping.responseDataExpression);
            if (options?.mapUndefinedResponses || (value !== undefined && value !== null)) {
              this.stateService.storeValueByExpression(responseDataMapping.stateKeyExpression, value);
            }
          }
        }
      } catch (error) {
        this.logger.errorToServer('handleServiceActivatorResult: Error in responseDataMapping', error);
        throw error;
      }
    });
  }
}

results matching ""

    No results matching ""