Skip to content

Fix undefined Benefit Product on payment plan listing#109

Open
Shahzaibahmad97 wants to merge 1 commit intodevelopfrom
fix/payment-plan-list-benefit-plan-undefined
Open

Fix undefined Benefit Product on payment plan listing#109
Shahzaibahmad97 wants to merge 1 commit intodevelopfrom
fix/payment-plan-list-benefit-plan-undefined

Conversation

@Shahzaibahmad97
Copy link
Copy Markdown

@Shahzaibahmad97 Shahzaibahmad97 commented Apr 16, 2026

Description

On the Payment Plans listing page (/front/paymentPlans), the Benefit Product column rendered each row's program picker label as "undefined…" on the very first render after the search results came in. Any subsequent state change (filter input, sort, etc.) made the value appear correctly, which made the bug look intermittent.

Root cause: the backend serialises the benefitPlan field of paymentPlan as a graphene JSONString wrapping a json.dumps(...) result, so the value arrives at the frontend double-encoded. The list reducer (CONTRIBUTIONPLAN_PAYMENTPLANS_RESP) was passing it through unparsed, while PaymentPlanSearcher.itemFormatters only did a single inline JSON.parse. Single-parsing a double-encoded string produces another string (not an object), so BenefitPlanPicker rendered ${value.code} ${value.name} as "undefined undefined". A second render re-ran the inline parse on the now-single-encoded string and produced the object — masking the bug after any user interaction.

This PR parses benefitPlan once in the reducer (double parse), mirroring the existing CONTRIBUTIONPLAN_CONTRIBUTIONPLANS_RESP handler, so consumers receive a proper object on the first render.

Type of Change

  • Feature
  • Bug fix
  • Chore (Refactor, Docs, CI/CD)
  • Other, please specify

Related Issue(s) / Task(s)

E2E Payment Tests


Changes

  • Parse benefitPlan (double parse, with null guard) in CONTRIBUTIONPLAN_PAYMENTPLANS_RESP so the list reducer produces objects with code/name already accessible.
  • No change to PaymentPlanSearcher.js — its existing defensive inline parse becomes a no-op when the value is already an object.

Behaviour Before / After

Scenario Before After
Initial in-app navigation to /front/paymentPlans Benefit Product column shows "undefined…" Benefit Product column shows the program code/name
Records re-fetched via Search filter First render shows "undefined…", fixed after any subsequent state change Correct value on the first render
Hard browser refresh Already worked Unchanged

Demo

To be added after manual verification.

Checklist

  • Pattern matches the existing CONTRIBUTIONPLAN_CONTRIBUTIONPLANS_RESP reducer handler
  • Null/undefined benefitPlan is guarded (returns null instead of throwing on JSON.parse)
  • Defensive inline parsing in PaymentPlanSearcher is preserved as a no-op fallback
  • No new redux state introduced; no API/GraphQL changes
  • Verified manually in a running stack

The PAYMENTPLANS list reducer was passing benefitPlan straight through
without parsing.  Because the backend serialises this field as a
graphene JSONString wrapping a json.dumps(...) result, the value
arrives at the frontend as a double-encoded JSON string.

PaymentPlanSearcher tried to compensate with an inline single
JSON.parse, but on a double-encoded input that produces another string
(not an object), so BenefitPlanPicker rendered the option label as
"undefined undefined" on the very first render.  Any subsequent state
change re-ran the inline parse on the now single-encoded string and
produced the object, masking the bug.

Parse benefitPlan in the reducer (double parse, mirroring the
CONTRIBUTIONPLAN_CONTRIBUTIONPLANS_RESP handler) so consumers receive a
proper object on the first render.  The defensive inline parse in the
searcher becomes a no-op for this code path.
@sonarqubecloud
Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant