# Common Pitfalls and How to Avoid Them ## Pitfall 1: No Debouncing **Problem:** ```javascript input.addEventListener('input', (e) => { performSearch(e.target.value); // API call on EVERY keystroke! }); ``` **Impact:** - Expensive (hundreds of unnecessary API calls) - Slow (race conditions, outdated results) - Rate limiting (429 errors) **Solution:** Always debounce (see Best Practices #1) ## Pitfall 2: Ignoring Session Tokens **Problem:** ```javascript // No session token = each request charged separately fetch('...suggest?q=query&access_token=xxx'); ``` **Impact:** - Costs 10-100x more than necessary - Budget blown on redundant charges **Solution:** Use session tokens (see Best Practices #2) ## Pitfall 3: No Geographic Context **Problem:** ```javascript // Searching globally for "Paris" { q: 'Paris'; } // Paris, France? Paris, Texas? Paris, Kentucky? ``` **Impact:** - Confusing results (wrong country) - Slower responses - Poor user experience **Solution:** ```javascript // Much better { q: 'Paris', country: 'US', proximity: user_location } ``` ## Pitfall 4: Poor Mobile UX **Problem:** ```html
Search result
``` **Impact:** - Frustrating to tap - Accidental selections - Bad reviews **Solution:** ```css .search-result { min-height: 48px; /* Android minimum */ padding: 12px; margin: 4px 0; } ``` ## Pitfall 5: Not Handling Empty Results **Problem:** ```javascript // Just shows empty container displayResults([]); // User sees blank space - is it loading? broken? ``` **Impact:** - User confusion - Is it working? **Solution:** ```javascript if (results.length === 0) { showMessage('No results found. Try a different search term.'); } ``` ## Pitfall 6: Blocking on Slow Networks **Problem:** ```javascript // No timeout = waits forever on slow network await fetch(searchUrl); ``` **Impact:** - Appears frozen - User frustration **Solution:** ```javascript const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), 5000); fetch(searchUrl, { signal: controller.signal }).finally(() => clearTimeout(timeout)); ``` ## Pitfall 7: Ignoring Result Types **Problem:** ```javascript // Treating all results the same displayResult(result.name); // But is it an address? POI? Region? ``` **Impact:** - Unclear what was selected - Wrong zoom level - Inappropriate markers **Solution:** ```javascript function handleResult(result) { const type = result.feature_type; if (type === 'poi') { map.flyTo({ center: coords, zoom: 17 }); // Close zoom addPOIMarker(result); } else if (type === 'address') { map.flyTo({ center: coords, zoom: 16 }); addAddressMarker(result); } else if (type === 'place') { map.flyTo({ center: coords, zoom: 12 }); // Wider view for city } } ``` ## Pitfall 8: Race Conditions **Problem:** ```javascript // Fast typing: "san francisco" // API responses arrive out of order: // "san f" results arrive AFTER "san francisco" results ``` **Impact:** - Wrong results displayed - Confusing UX **Solution:** ```javascript let searchCounter = 0; async function performSearch(query) { const currentSearch = ++searchCounter; const results = await fetchResults(query); // Only display if this is still the latest search if (currentSearch === searchCounter) { displayResults(results); } } ```