From 2cb2366b012e851da8f10b82434cef909caa88fc Mon Sep 17 00:00:00 2001 From: PorunC <09982.misaka@gmail.com> Date: Wed, 29 Oct 2025 20:46:08 +0800 Subject: [PATCH] Fix: Add comprehensive null safety checks to CompetitionPage component Root cause analysis: The previous fix (0cb1f37) only addressed App.tsx Debug Info section, but missed CompetitionPage.tsx which also directly accesses trader data fields without null safety checks. When competition data is loading or incomplete, trader objects may exist but contain undefined fields (total_pnl, total_equity, etc.), causing: "TypeError: Cannot read properties of undefined (reading 'total_pnl')" Fixed locations in CompetitionPage.tsx: 1. Line 76-77: Leader display in header (total_pnl, total_pnl_pct) 2. Line 142: Leaderboard total_equity display 3. Line 151-157: Leaderboard P&L section (total_pnl checks and displays) 4. Line 229-230: Head-to-Head comparison (total_pnl display) Changes applied: - Replace direct property access with optional chaining (?.) - Use nullish coalescing (?? 0) for numeric comparisons - Add fallback values ('0.00') for undefined fields - Ensure consistent null safety across all trader data displays This completes the null safety coverage for the entire frontend. Fixes: TypeError in CompetitionPage at index-R21Yay1P.js:116:51447 Co-Authored-By: tinkle-community --- web/src/components/CompetitionPage.tsx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/web/src/components/CompetitionPage.tsx b/web/src/components/CompetitionPage.tsx index a72f6dfb..bc549e38 100644 --- a/web/src/components/CompetitionPage.tsx +++ b/web/src/components/CompetitionPage.tsx @@ -73,8 +73,8 @@ export function CompetitionPage() {
{t('leader', language)}
{leader?.trader_name}
-
= 0 ? '#0ECB81' : '#F6465D' }}> - {leader.total_pnl >= 0 ? '+' : ''}{leader.total_pnl_pct.toFixed(2)}% +
= 0 ? '#0ECB81' : '#F6465D' }}> + {(leader?.total_pnl ?? 0) >= 0 ? '+' : ''}{leader?.total_pnl_pct?.toFixed(2) || '0.00'}%
@@ -139,7 +139,7 @@ export function CompetitionPage() {
{t('equity', language)}
- {trader.total_equity.toFixed(2)} + {trader.total_equity?.toFixed(2) || '0.00'}
@@ -148,13 +148,13 @@ export function CompetitionPage() {
{t('pnl', language)}
= 0 ? '#0ECB81' : '#F6465D' }} + style={{ color: (trader.total_pnl ?? 0) >= 0 ? '#0ECB81' : '#F6465D' }} > - {trader.total_pnl >= 0 ? '+' : ''} - {trader.total_pnl_pct.toFixed(2)}% + {(trader.total_pnl ?? 0) >= 0 ? '+' : ''} + {trader.total_pnl_pct?.toFixed(2) || '0.00'}%
- {trader.total_pnl >= 0 ? '+' : ''}{trader.total_pnl.toFixed(2)} + {(trader.total_pnl ?? 0) >= 0 ? '+' : ''}{trader.total_pnl?.toFixed(2) || '0.00'}
@@ -226,8 +226,8 @@ export function CompetitionPage() { > {trader.trader_name} -
= 0 ? '#0ECB81' : '#F6465D' }}> - {trader.total_pnl >= 0 ? '+' : ''}{trader.total_pnl_pct.toFixed(2)}% +
= 0 ? '#0ECB81' : '#F6465D' }}> + {(trader.total_pnl ?? 0) >= 0 ? '+' : ''}{trader.total_pnl_pct?.toFixed(2) || '0.00'}%
{isWinning && gap > 0 && (