LogoTRUONG PHAM
Home
Projects
Blogs
YouTube
Contact

Newsletter

Stay updated with technical artifacts and engineering insights.

LogoTRUONG PHAM

Building scalable software and sharing insights on technology & life.

Sitemap

  • Home
  • Projects
  • Blogs
  • YouTube
  • Contact

Connect

  • GitHub
  • LinkedIn
  • Email
  • YouTube

© 2024 TRUONG PHAM. © All rights reserved.

Privacy PolicyTerms of Service
Back
Blog #32: Friday Afternoon, 800 Lines of Code, and a Miscalculation
50 FRONTEND LESSONS – HARD-EARNED EXPERIENCES

Blog #32: Friday Afternoon, 800 Lines of Code, and a Miscalculation

When mixing business logic into a UI component turns bug fixing into a multi-hour nightmare.

TP
Truong PhamSoftware Engineer
PublishedJune 28, 2024

It's 4:30 PM on a Friday. I'm packing up to head home when an urgent ticket comes in: "Customers are being charged the wrong order value when applying 2 discount codes at once." I open the OrderSummary.tsx file. 800 lines of code appear before my eyes.

The JSX display section is tightly interwoven with map, filter functions, and logic for calculating percentages, taxes, and shipping fees. Reading the code feels suffocating. Business logic is "whispering" right alongside <div> and <button> tags.

Initially, I blamed the backend: "Surely the API returned the wrong value." But checking the Network tab, the data was perfectly accurate. The fault was mine. On line 452, an if/else condition was written backwards, causing shipping fees to be added instead of deducted.

1. What happened?

A simple logic error became extremely difficult to find because it was buried deep within an oversized UI component. The lack of Separation of Concerns turned this file into a "Big Ball of Mud."

2. What I thought the cause was

I assumed it was because data from the API wasn't formatted with the correct type (string vs number). I spent time writing Number() wrappers all over the place to force types, but it still didn't solve the problem.

3. How I debugged it

Since I couldn't quickly write Unit Tests for this logic (due to it being coupled with the UI), I had to use console.log at every calculation step. Each time I checked the result, I had to wait for Webpack's hot-reload and interact with the UI to trigger the logic.

4. The moment of realization

I realized I was lost in a maze of my own making. Why did I let a UI component be responsible for calculating a complex financial problem? If this logic had been in a separate function, I could have caught the error immediately with a simple test suite.

5. The fix

  • Quick patch: Fix the incorrect if/else condition to make the release.
  • Real fix: Extract all calculation logic into Pure Functions within the utils or services directory. The UI should have a single responsibility: Receive data and display it.

6. Looking back

I was too lazy, thinking that "writing it together is faster." Mixing UI and Logic is the quickest way to turn a project into "legacy code" after just a few weeks of development. If I were designing it again, I would mandate that all calculation logic be unit tested independently before being brought into a component.

Series • Part 32 of 50

50 FRONTEND LESSONS – HARD-EARNED EXPERIENCES

NextBlog #33: 10 PM and the 'Infinite Loop' of Punishment
Blog #31: 1 AM and the Search for the 'Missing' File
27Blog #27: useEffect is not the place for doing all synchronizing logic28Blog #28: The naivety of believing setState is an immediate assignment29Blog #29: When 'Controlled Component' turns into a performance burden30Blog #30: A giant State Object doesn't make your code cleaner31Blog #31: 1 AM and the Search for the 'Missing' File32Blog #32: Friday Afternoon, 800 Lines of Code, and a MiscalculationReading33Blog #33: 10 PM and the 'Infinite Loop' of Punishment34Blog #34: My Machine Runs Smooth, the User's Machine Smokes35Blog #35: Clean Architecture – The Dream and the Harsh Reality36Blog #36: Touching Legacy Code – When a refactor effort becomes a disaster37Blog #37: The Reusability Trap – When a 'multi-purpose' Component becomes a burden
TP

Written by Truong Pham

Software Engineer passionate about building high-performance systems and meaningful experiences.

Read more articles