mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-05 03:50:59 +08:00
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 <tinklefund@gmail.com>
This commit is contained in:
@@ -73,8 +73,8 @@ export function CompetitionPage() {
|
||||
<div className="text-right">
|
||||
<div className="text-xs mb-1" style={{ color: '#848E9C' }}>{t('leader', language)}</div>
|
||||
<div className="text-lg font-bold" style={{ color: '#F0B90B' }}>{leader?.trader_name}</div>
|
||||
<div className="text-sm font-semibold" style={{ color: leader.total_pnl >= 0 ? '#0ECB81' : '#F6465D' }}>
|
||||
{leader.total_pnl >= 0 ? '+' : ''}{leader.total_pnl_pct.toFixed(2)}%
|
||||
<div className="text-sm font-semibold" style={{ color: (leader?.total_pnl ?? 0) >= 0 ? '#0ECB81' : '#F6465D' }}>
|
||||
{(leader?.total_pnl ?? 0) >= 0 ? '+' : ''}{leader?.total_pnl_pct?.toFixed(2) || '0.00'}%
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -139,7 +139,7 @@ export function CompetitionPage() {
|
||||
<div className="text-right">
|
||||
<div className="text-xs" style={{ color: '#848E9C' }}>{t('equity', language)}</div>
|
||||
<div className="text-sm font-bold mono" style={{ color: '#EAECEF' }}>
|
||||
{trader.total_equity.toFixed(2)}
|
||||
{trader.total_equity?.toFixed(2) || '0.00'}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -148,13 +148,13 @@ export function CompetitionPage() {
|
||||
<div className="text-xs" style={{ color: '#848E9C' }}>{t('pnl', language)}</div>
|
||||
<div
|
||||
className="text-lg font-bold mono"
|
||||
style={{ color: trader.total_pnl >= 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'}%
|
||||
</div>
|
||||
<div className="text-xs mono" style={{ color: '#848E9C' }}>
|
||||
{trader.total_pnl >= 0 ? '+' : ''}{trader.total_pnl.toFixed(2)}
|
||||
{(trader.total_pnl ?? 0) >= 0 ? '+' : ''}{trader.total_pnl?.toFixed(2) || '0.00'}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -226,8 +226,8 @@ export function CompetitionPage() {
|
||||
>
|
||||
{trader.trader_name}
|
||||
</div>
|
||||
<div className="text-2xl font-bold mono mb-1" style={{ color: trader.total_pnl >= 0 ? '#0ECB81' : '#F6465D' }}>
|
||||
{trader.total_pnl >= 0 ? '+' : ''}{trader.total_pnl_pct.toFixed(2)}%
|
||||
<div className="text-2xl font-bold mono mb-1" style={{ color: (trader.total_pnl ?? 0) >= 0 ? '#0ECB81' : '#F6465D' }}>
|
||||
{(trader.total_pnl ?? 0) >= 0 ? '+' : ''}{trader.total_pnl_pct?.toFixed(2) || '0.00'}%
|
||||
</div>
|
||||
{isWinning && gap > 0 && (
|
||||
<div className="text-xs font-semibold" style={{ color: '#0ECB81' }}>
|
||||
|
||||
Reference in New Issue
Block a user