Fixing the “D.map is not a function” crash by tightening DB indexes and normalizing the API payload
Fixing the “D.map is not a function” crash by tightening DB indexes and normalizing the API payload TL;DR: I added missing PostgreSQL indexes in apps/api/src/db/db.ts and forced the /condos/metrics endpoint to always return an array. The change stopped the runtime TypeError: D.map is not a function in the React selector and restored correct KPI calculations. The Problem Our internal “Condo Dashboard” started throwing a JavaScript error in production: TypeError: D.map is not a function at render (src/components/CondoSelector.tsx:45) at D.map(e=>(0,a.jsx)("option",{value:e.id,children:e.name},e.id)) D is the data array used to populate a <select> with condo options. When the page loaded, the dropdown was empty and the whole component crashed. The API call that feeds D ( GET /api/condos/metrics ) was supposed to return an array of objects { id, name } , but under certain conditions it returned null or a single object, breaking the .map call. The root cause turned out to be duplicate rows in the broker_tokens table that caused the query to return a malformed result set. Those duplicates were a side‑effect of missing unique indexes on the broker_tokens and condo_metrics tables. What I Tried First Guarding the Front‑end – I added a quick check in CondoSelector.tsx : const options = Array . isArray ( data ) ? data : []; This silenced the error, but the UI still showed no options because the API kept returning the wrong shape. It was a band‑aid, not a fix. Manual Data Normalization – In the API controller I forced the result to an array: const rows = await db . query ( sql ); return res . json ( Array . isArray ( rows ) ? rows : [ rows ]); This produced duplicate entries and confused downstream calculations. The KPI numbers in the dashboard were still off. Both approaches addressed the symptom but left the database inconsistency untouched, so the bug could re‑appear anytime new data landed. The Implementation 1. Add proper indexes (the real fix) The missing indexes allowed