This is my template { "_id" : ObjectId("65bbf40aa3efbe1df2123d78"), "eventType" : "OP_VISIT_CREATED", "entityCode" : 115, "entityName" : "Sankara Hospitals", "smsTemplate" : "Dear {patient.fullName},\nThank you for visiting {entityName}.\nYour UHID No. is {patient.mrn.documentNumber}, please use this number for all further communications.", "whatsappTemplate" : { "name" : "registration", "namespace" : "12dfb464_ca0d_47f6_b753_5e759bbf2c34", "components" : [ { "type" : "text", "parameters" : [ { "type" : "text", "text" : "{patient.fullName}" }, { "type" : "text", "text" : "{entityName}" }, { "type" : "text", "text" : "MRN" } ] } ] }, "emailTemplate" : { "subject" : "Welcome to {entityName}", "body" : "Dear {patient.fullName},\n\nThank you for visiting {entityName}.\n\nYour UHID No. is {patient.mrn.documentNumber}, please use this number for all further communications.\n\nBest regards,\nThe {entityName} Team" } } This is my data { "entityRID": 84, "entityCode": "115", "enterpriseCode": "84", "datetime": "31/01/2024 10:21 AM", "unitRID": 3188, "patient": { "referencePatientId": 0, "address": "GRAM- DATODA, KHANDWA ROAD", "updateCount": 0, "mrn": { "sequenceNumber": 19520656, "documentNumber": "SECIND/102907/24" }, "fullName": "Narottam", "isVIP": false, "valid": 0, "phone": "9977309143", "isInternational": false, "isUnknown": false, "medicsId": 0, "isExpired": 0, "email": "", "confidential": false }, "billPrintBase64": "JVBERi0xLjUKJeL", "userRID": 13426480, "bill": { "secondaryPayerPayeable": 0, "updateCount": 0, "netAmount": 300, "billVersion": 1, "discountAmount": 0, "billDate": "31/01/2024", "grossAmount": 300, "categoryName": "MAIN", "primaryPayerPayeable": 0, "billItemList": { "list": [ { "loadFactor": 0.75, "threshold": 96 } ] }, "statusName": "FULLY_PAID", "category": 1, "taxAmount": 0, "printableNumber": { "sequenceNumber": 39428, "documentNumber": "IND/SOP/23/39428" }, "effectiveDate": "31/01/2024", "entity": { "value": "86" }, "status": 0 }, "description": "Object created", "enterpriseEntityRID": 84, "visit": { "date": "31/01/2024", "updateCount": 0, "gender": { "name": "Male", "index": 1 }, "freeRemainingCount": 0, "consultingDoctor": { "value": "14207" }, "visitedEntity": { "value": "84" }, "visitNumber": { "sequenceNumber": 1, "documentNumber": "" }, "patientMRN": "SECIND/102907/24", "typeName": "OP", "leadRemarks": "", "type": 1, "patientAgeInYears": 0, "speciality": { "name": "Glaucoma", "index": 521021 }, "patientAgeInDays": 0, "visitCategory": 0, "leadNo": "", "statusName": "Draft", "medicsId": 0, "patientAgeInMonths": 0, "time": "10:21 AM", "id": { "value": "10334904" }, "isEmrSealed": false, "status": 0 }, "type": "OP_VISIT_CREATED", "receiptNumber": "IND/REC/23/56067" } These are the function which i'm using to handle the filling of the templates fillTemplatePlaceholders(template, eventData) { let filledTemplate = template; // Implement custom logic to replace ${placeholder} in the template for (const key of Object.keys(eventData)) { const placeholder = new RegExp(`\\$\\{${key}\\}`, "g"); filledTemplate = filledTemplate.replace(placeholder, eventData[key]); } return filledTemplate; } fillWhatsAppTemplatePlaceholders(template, eventData) { let filledTemplate = template; // Implement custom logic to replace ${placeholder} in the template for (const key of Object.keys(eventData)) { const placeholder = new RegExp(`\\$\\{${key}\\}`, "g"); filledTemplate = filledTemplate.replace(placeholder, eventData[key]); } return filledTemplate; } fillEmailTemplatePlaceholders(template, eventData) { let filledSubject = template.subject; let filledBody = template.body; // Implement custom logic to replace ${placeholder} in the template for (const key of Object.keys(eventData)) { const placeholder = new RegExp(`\\$\\{${key}\\}`, "g"); filledSubject = filledSubject.replace(placeholder, eventData[key]); filledBody = filledBody.replace(placeholder, eventData[key]); } return { subject: filledSubject, body: filledBody }; } But this is not working as expected, is it becuase of the nested objects ? what is the best possible way to do this in a robust and scalable way