File
Methods
|
Public
mapStateToRequest
|
mapStateToRequest(requestDataMapping: ServiceActivatorDataMappingForRequesting[])
|
|
|
Parameters :
| Name |
Type |
Optional |
| requestDataMapping |
ServiceActivatorDataMappingForRequesting[]
|
No
|
|
|
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;
}
});
}
}