From 1c5851d053cd8daf475a5f687524772166d47cb4 Mon Sep 17 00:00:00 2001 From: Alexis Bruneteau Date: Fri, 7 Nov 2025 19:06:34 +0100 Subject: [PATCH] fix: Prevent frontend TypeError from undefined array access MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix undefined variable crashes when accessing property 'length' on undefined: - "can't access property 'length', e is undefined" CHANGES: 1. Election detail page ([id]/page.tsx): - Ensure candidates array exists when fetching election data - Default to empty array if API returns undefined candidates 2. Active elections list page (active/page.tsx): - Validate API response is an array before processing - Ensure each election has candidates array with fallback 3. Blockchain visualizer (blockchain-visualizer.tsx): - Add optional chaining check before accessing data.blocks - Prevent crashes when data prop is undefined All changes follow defensive programming practices: - No more direct property access without null checks - Array fallbacks ensure predictable behavior - Optional chaining used consistently This fixes the error that occurred when navigating to election pages. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../frontend/app/dashboard/votes/active/[id]/page.tsx | 7 ++++++- .../frontend/app/dashboard/votes/active/page.tsx | 7 ++++++- .../frontend/components/blockchain-visualizer.tsx | 4 ++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/e-voting-system/frontend/app/dashboard/votes/active/[id]/page.tsx b/e-voting-system/frontend/app/dashboard/votes/active/[id]/page.tsx index adbd5c9..ae6d168 100644 --- a/e-voting-system/frontend/app/dashboard/votes/active/[id]/page.tsx +++ b/e-voting-system/frontend/app/dashboard/votes/active/[id]/page.tsx @@ -52,7 +52,12 @@ export default function VoteDetailPage() { } const data = await response.json() - setElection(data) + // Ensure candidates array exists, default to empty array if undefined + const election = { + ...data, + candidates: data.candidates || [] + } + setElection(election) } catch (err) { const message = err instanceof Error ? err.message : "Erreur lors du chargement" setError(message) diff --git a/e-voting-system/frontend/app/dashboard/votes/active/page.tsx b/e-voting-system/frontend/app/dashboard/votes/active/page.tsx index 316bacf..365a374 100644 --- a/e-voting-system/frontend/app/dashboard/votes/active/page.tsx +++ b/e-voting-system/frontend/app/dashboard/votes/active/page.tsx @@ -39,7 +39,12 @@ export default function ActiveVotesPage() { } const data = await response.json() - setElections(data || []) + // Ensure elections is an array and each has candidates + const elections = Array.isArray(data) ? data.map(e => ({ + ...e, + candidates: e.candidates || [] + })) : [] + setElections(elections) } catch (err) { const message = err instanceof Error ? err.message : "Erreur lors du chargement" setError(message) diff --git a/e-voting-system/frontend/components/blockchain-visualizer.tsx b/e-voting-system/frontend/components/blockchain-visualizer.tsx index d79a84c..aca549b 100644 --- a/e-voting-system/frontend/components/blockchain-visualizer.tsx +++ b/e-voting-system/frontend/components/blockchain-visualizer.tsx @@ -54,14 +54,14 @@ export function BlockchainVisualizer({ // Animate blocks on load useEffect(() => { - if (data.blocks.length > 0) { + if (data?.blocks && data.blocks.length > 0) { data.blocks.forEach((_, index) => { setTimeout(() => { setAnimatingBlocks((prev) => [...prev, index]) }, index * 100) }) } - }, [data.blocks]) + }, [data?.blocks]) const toggleBlockExpand = (index: number) => { setExpandedBlocks((prev) =>