Files
MyClub/DOCS/BLOG_MATCH_LINK_FIX_2025.md
Tomas Dvorak 77213f4e83 dev day #65
2025-10-19 17:16:57 +02:00

3.2 KiB

Blog Match Link Fix - October 2025

Problem

React Error #310 (Maximum update depth exceeded) - infinite render loop caused by backend returning map[string]interface{} instead of Article structs. Each map created new object references, triggering infinite re-renders in React useEffect hooks.

Root Cause

Previous attempt to add match link data to article JSON responses used helper functions that returned maps instead of structs. This broke React's referential equality checks.

Solution

1. Added MatchLink Field to Article Model

File: internal/models/models.go

type Article struct {
    // ... existing fields ...
    
    // Match link (loaded separately, not stored in this table)
    MatchLink *ArticleMatchLink `gorm:"-" json:"match_link,omitempty"`
}

The gorm:"-" tag prevents GORM from treating it as a database column, and omitempty keeps it out of JSON if nil.

2. Updated Backend Controllers

File: internal/controllers/base_controller.go

GetArticle (single article by ID)

  • Loads match link after fetching article
  • Sets art.MatchLink if found

GetArticles (paginated list)

  • Batch loads all match links for returned articles in single query
  • Maps match links to articles by ID for O(1) lookup
  • Efficient: one extra query regardless of result set size

GetArticleBySlug (single article by slug)

  • Same as GetArticle - loads match link if exists

3. Simplified Frontend

File: frontend/src/pages/admin/ArticlesAdminPage.tsx

  • Removed: Redundant useEffect that fetched match link separately
  • Kept: openEdit() function that extracts match_link from article data
  • Result: Fewer API calls, no infinite loops

Benefits

  1. No Infinite Loops: Article structs maintain referential equality
  2. Complete Data: Article JSON now includes both competition AND match data
  3. Better Performance: Batch loading for lists (N+1 → 2 queries)
  4. Backward Compatible: Match link is optional (omitempty)
  5. Cleaner Code: No complex map transformations

The album link reuse feature was already implemented (lines 400-415 in ArticlesAdminPage.tsx). When photos are selected in the Obsah tab, both the album link AND photos are automatically populated in the Media tab.

Enhancement made: Improved UI feedback with green background and clear status messages when album is loaded.

Article JSON Structure

Articles now include:

{
  "id": 123,
  "title": "Match Report",
  "category_name": "A třída",
  "gallery_album_url": "https://eu.zonerama.com/...",
  "youtube_video_id": "abc123",
  "match_link": {
    "external_match_id": "match-abc-123",
    "title": "Home Team vs Away Team"
  }
}

Testing

Test that:

  1. No React infinite loop errors
  2. Match link appears in article JSON responses
  3. Match link displays correctly in admin UI
  4. Album link persists between Obsah and Media tabs
  5. All article endpoints work (GetArticle, GetArticles, GetArticleBySlug)

Files Modified

  • internal/models/models.go - Added MatchLink field
  • internal/controllers/base_controller.go - Load match links in 3 endpoints
  • frontend/src/pages/admin/ArticlesAdminPage.tsx - Removed redundant fetch, improved UI