I'm currently working on a NestJS application that communicates with SAP (and some other external applications), and unfortunately, SAP requires some very specificly-named fields. To be precise, for some cases, I need to send over 70 fields to it and it in other cases, a request might return over than 280 fields.
Since I am not able to modify SAP, I'm forced to work with fields that goes against my application's naming patterns (camelCase and readable), as SAP uses SCREAMING_SNAKE_CASE with abbreviations, numbers and even some words that mix up english and german words.
Now, I know there are some not so practicals approaches to this (like parsing each field individually), but is there any that would save me time or at least make everything cleaner without having to parse fields manually?
Edit: Here's an example of what SAP returns to my application
PLNT_FABRIZIEREN_C: '253D',
MRKD_PRODUCTS: ['PRODUCT1', 'PRODUCT2'],
NEUES_PRDKT: TRUE
And the equivalent in my application:
factoryPlantCode: '253D',
markedProducts: ['PRODUCT1', 'PRODUCT2'],
isNewProduct: true
I need to completely change a fields name when saving it on my application so I'm still using camelCase but still send it back with the name SAP knows.
You can try something like this. All you need to do is to add the keys from SAP in key and set value as the key you want to use in your application.
const mappings = {
PLNT_FABRIZIEREN_C: "factoryPlantCode",
MRKD_PRODUCTS: "markedProducts",
NEUES_PRDKT: "isNewProduct"
}
const getFormattedVersion = (data) => {
const returnData = {};
Object.keys(data).forEach(key => {
returnData[mappings[key]] = data[key];
})
return returnData
}
const getSAPSupportedVersion = (data) =>{
const returnData = {};
Object.keys(data).forEach(key => {
const mappingKeys = Object.keys(mappings)
const mappingValues = Object.values(mappings)
const mappedKey = mappingKeys[mappingValues.indexOf(key)];
returnData[mappedKey] = data[key];
})
return returnData
}
console.log(
getFormattedVersion({
PLNT_FABRIZIEREN_C: '253D',
MRKD_PRODUCTS: ['PRODUCT1', 'PRODUCT2'],
NEUES_PRDKT: true
})
)
console.log(
getSAPSupportedVersion({
factoryPlantCode: "253D",
isNewProduct: true,
markedProducts: ["PRODUCT1", "PRODUCT2"]
})
)
Thanks Sony Bamniya for answering my question, but I figured another way of dealing with that problem. By using class-transformer package, I was able to rename my fields:
@Expose({ name: 'factoryPlantCode' })
PLNT_FABRIZIEREN_C: string
@Expose({ name: 'markedProducts' })
MRKD_PRODUCTS: string;
@Expose({ name: 'isNewProduct' })
NEUES_PRDKT: boolean;
I still had the issue with SCREAMING_SNAKE_CASE fields, but that was easy to fix: I added an interceptor that parsed all those fields from SCREAMING_SNAKE_CASE to camelCase using lodash .camelCase and a hand made iteration using Object.entries(payload).
It's also worth mentioning my DTO has a constructor:
constructor(rawPayload) {
Object.assign(this, rawPayload);
}
And after populating my DTO, I had to turn it into a plain object using class-transformer classToPlain() method (I could parse it back to a DTO after parsing it to plain, but I didn't need it).
Hope this helps somebody!