From ffea0598cd2bd6467913f58eeb48fd4b80c80869 Mon Sep 17 00:00:00 2001
From: Vrishab Srivatsa <136090360+vsrivatsa-juspay@users.noreply.github.com>
Date: Tue, 13 Feb 2024 17:42:48 +0530
Subject: [PATCH] Fix/semiloaded state race condition (#163)
---
src/Components/DynamicFields.res | 46 ++++++++++++++++++----------
src/LoaderController.res | 20 +++++-------
src/PaymentElement.res | 3 +-
src/Utilities/DynamicFieldsUtils.res | 3 +-
4 files changed, 39 insertions(+), 33 deletions(-)
diff --git a/src/Components/DynamicFields.res b/src/Components/DynamicFields.res
index 979168ace..bf2e89de3 100644
--- a/src/Components/DynamicFields.res
+++ b/src/Components/DynamicFields.res
@@ -21,7 +21,7 @@ let make = (
let {billingAddress} = Recoil.useRecoilValueFromAtom(optionAtom)
//<...>//
- let paymentMethodTypes =
+ let paymentMethodTypes = React.useMemo3(() => {
PaymentMethodsRecord.getPaymentMethodTypeFromList(
~list,
~paymentMethod,
@@ -30,19 +30,25 @@ let make = (
~paymentMethodName=paymentMethodType,
),
)->Belt.Option.getWithDefault(PaymentMethodsRecord.defaultPaymentMethodType)
+ }, (list, paymentMethod, paymentMethodType))
- let requiredFieldsWithBillingDetails = if paymentMethod === "card" {
- paymentMethodTypes.required_fields
- } else if (
- PaymentMethodsRecord.dynamicFieldsEnabledPaymentMethods->Js.Array2.includes(paymentMethodType)
- ) {
- paymentMethodTypes.required_fields
- } else {
- []
- }
+ let requiredFieldsWithBillingDetails = React.useMemo3(() => {
+ if paymentMethod === "card" {
+ paymentMethodTypes.required_fields
+ } else if (
+ PaymentMethodsRecord.dynamicFieldsEnabledPaymentMethods->Js.Array2.includes(paymentMethodType)
+ ) {
+ paymentMethodTypes.required_fields
+ } else {
+ []
+ }
+ }, (paymentMethod, paymentMethodTypes.required_fields, paymentMethodType))
- let requiredFields =
- requiredFieldsWithBillingDetails->DynamicFieldsUtils.removeBillingDetailsIfUseBillingAddress
+ let requiredFields = React.useMemo1(() => {
+ requiredFieldsWithBillingDetails->DynamicFieldsUtils.removeBillingDetailsIfUseBillingAddress(
+ billingAddress,
+ )
+ }, [requiredFieldsWithBillingDetails])
let isAllStoredCardsHaveName = React.useMemo1(() => {
PaymentType.getIsAllStoredCardsHaveName(savedCards)
@@ -265,24 +271,30 @@ let make = (
}
}
- let dynamicFieldsToRenderOutsideBilling =
+ let dynamicFieldsToRenderOutsideBilling = React.useMemo1(() => {
fieldsArr->Js.Array2.filter(field =>
field->DynamicFieldsUtils.isFieldTypeToRenderOutsideBilling
)
+ }, [fieldsArr])
- let dynamicFieldsToRenderInsideBilling =
+ let dynamicFieldsToRenderInsideBilling = React.useMemo1(() => {
fieldsArr->Js.Array2.filter(field =>
!(field->DynamicFieldsUtils.isFieldTypeToRenderOutsideBilling)
)
+ }, [fieldsArr])
- let isInfoElementPresent = dynamicFieldsToRenderInsideBilling->Js.Array2.includes(InfoElement)
+ let isInfoElementPresent = React.useMemo1(() => {
+ dynamicFieldsToRenderInsideBilling->Js.Array2.includes(InfoElement)
+ }, [dynamicFieldsToRenderInsideBilling])
- let isOnlyInfoElementPresent =
+ let isOnlyInfoElementPresent = React.useMemo2(() => {
dynamicFieldsToRenderInsideBilling->Js.Array2.length === 1 && isInfoElementPresent
+ }, (dynamicFieldsToRenderInsideBilling, isInfoElementPresent))
- let isRenderDynamicFieldsInsideBilling =
+ let isRenderDynamicFieldsInsideBilling = React.useMemo2(() => {
dynamicFieldsToRenderInsideBilling->Js.Array2.length > 0 &&
(dynamicFieldsToRenderInsideBilling->Js.Array2.length > 1 || !isOnlyInfoElementPresent)
+ }, (dynamicFieldsToRenderInsideBilling, isOnlyInfoElementPresent))
React.useEffect1(() => {
let fieldsArrStr = fieldsArr->Js.Array2.map(field => {
diff --git a/src/LoaderController.res b/src/LoaderController.res
index 955211b86..abee9d6a1 100644
--- a/src/LoaderController.res
+++ b/src/LoaderController.res
@@ -125,6 +125,14 @@ let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger) => {
handlePostMessage([("iframeMounted", true->Js.Json.boolean)])
handlePostMessage([("applePayMounted", true->Js.Json.boolean)])
logger.setLogInitiated()
+ switch paymentlist {
+ | Loaded(_)
+ | LoadError(_) => ()
+ | _ =>
+ setList(._ =>
+ showCardFormByDefault && Utils.checkPriorityList(paymentMethodOrder) ? SemiLoaded : Loading
+ )
+ }
Window.addEventListener("click", ev =>
handleOnClickPostMessage(~targetOrigin=keys.parentURL, ev)
)
@@ -358,18 +366,6 @@ let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger) => {
handleMessage(handleFun, "Error in parsing sent Data")
}, (showCardFormByDefault, paymentMethodOrder))
- React.useEffect1(() => {
- switch paymentlist {
- | Loaded(_)
- | LoadError(_) => ()
- | _ =>
- setList(._ =>
- showCardFormByDefault && Utils.checkPriorityList(paymentMethodOrder) ? SemiLoaded : Loading
- )
- }
- None
- }, [paymentlist])
-
let observer = ResizeObserver.newResizerObserver(entries => {
entries
->Js.Array2.map(item => {
diff --git a/src/PaymentElement.res b/src/PaymentElement.res
index 3d189bccf..1e8240830 100644
--- a/src/PaymentElement.res
+++ b/src/PaymentElement.res
@@ -20,7 +20,6 @@ let make = (
)
let isApplePayReady = Recoil.useRecoilValueFromAtom(isApplePayReady)
let isGooglePayReady = Recoil.useRecoilValueFromAtom(isGooglePayReady)
- let pmList = Recoil.useRecoilValueFromAtom(list)
let methodslist = Recoil.useRecoilValueFromAtom(list)
let paymentOrder = paymentMethodOrder->Utils.getOptionalArr->Utils.removeDuplicate
let (sessions, setSessions) = React.useState(_ => Js.Dict.empty()->Js.Json.object_)
@@ -319,7 +318,7 @@ let make = (
- {switch pmList {
+ {switch methodslist {
| LoadError(_) => React.null
| _ =>
,
+ billingAddress: PaymentType.billingAddress,
) => {
- let {billingAddress} = Recoil.useRecoilValueFromAtom(RecoilAtoms.optionAtom)
-
if billingAddress.isUseBillingAddress {
requiredFields->Js.Array2.filter(requiredField => {
!(requiredField.field_type->isBillingAddressFieldType)