Troubleshooting
Common issues and their solutions when working with the Route Optimization Map library.
Google Maps Issues
Map Not Displaying
Problem: The map container appears empty or shows a gray area.
Solutions:
Check API Key
typescript// Verify your API key is correct const config: MapConfig = { apiKey: 'YOUR_ACTUAL_API_KEY', // Not 'YOUR_API_KEY' };Enable Required APIs
- Go to Google Cloud Console
- Enable "Maps JavaScript API"
- Enable "Routes API" (for route optimization)
- Enable "Places API" (if using places features)
Check Container Size
css.map-container { width: 100%; height: 600px; /* Must have explicit height */ }Wait for Map to Load
typescript// React const { mapRef, isReady } = useRouteMap({ apiKey: 'YOUR_API_KEY' }); useEffect(() => { if (isReady) { console.log('Map is ready'); } }, [isReady]);
API Key Errors
Problem: Console shows "InvalidKeyMapError" or "RefererNotAllowedMapError".
Solutions:
Invalid API Key
typescript// Check for typos, extra spaces, or invalid characters const apiKey = process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY?.trim();Referrer Restrictions
- In Google Cloud Console, go to API Key restrictions
- Add your domain to HTTP referrers:
localhost:*for developmentyourdomain.com/*for production*.yourdomain.com/*for subdomains
API Restrictions
- Ensure the API key has access to required APIs
- Check quota limits haven't been exceeded
Rate Limiting
Problem: "OVER_QUERY_LIMIT" error appears.
Solutions:
Implement Request Throttling
typescriptimport { debounce } from 'lodash-es'; const debouncedOptimize = debounce(async (request: OptimizationRequest) => { await optimizer.optimize(request); }, 1000);Add Retry Logic
typescriptasync function optimizeWithRetry( request: OptimizationRequest, maxRetries = 3 ): Promise<OptimizationResponse> { for (let i = 0; i < maxRetries; i++) { try { return await optimizer.optimize(request); } catch (error) { if (error.message.includes('OVER_QUERY_LIMIT')) { await new Promise((resolve) => setTimeout(resolve, Math.pow(2, i) * 1000)); continue; } throw error; } } throw new Error('Max retries exceeded'); }Check Billing
- Verify billing is enabled in Google Cloud Console
- Check if daily quota limits have been reached
React Issues
Map Not Rendering in React
Problem: Map doesn't appear in React component.
Solutions:
Check Ref Initialization
typescriptfunction MapComponent() { const { mapRef, isReady } = useRouteMap({ apiKey: process.env.REACT_APP_GOOGLE_MAPS_API_KEY }); // ✅ Correct - ref is attached return <div ref={mapRef} style={{ width: '100%', height: '600px' }} />; // ❌ Wrong - missing ref // return <div style={{ width: '100%', height: '600px' }} />; }Environment Variables
bash# .env REACT_APP_GOOGLE_MAPS_API_KEY=your_api_key_here # Next.js NEXT_PUBLIC_GOOGLE_MAPS_API_KEY=your_api_key_here # Vite VITE_GOOGLE_MAPS_API_KEY=your_api_key_hereStrictMode Issues
typescript// Remove StrictMode if it causes double initialization // index.tsx root.render( // <React.StrictMode> // Comment out for testing <App /> // </React.StrictMode> );
Infinite Re-renders
Problem: Component re-renders infinitely.
Solutions:
Memoize Callbacks
typescript// ❌ Wrong - Creates new function on every render const handleClick = () => console.log('clicked'); // ✅ Correct - Memoized callback const handleClick = useCallback(() => { console.log('clicked'); }, []);Memoize Objects
typescript// ❌ Wrong - New object on every render const route = { stops: [...], options: { ... }, }; // ✅ Correct - Memoized object const route = useMemo(() => ({ stops: [...], options: { ... }, }), [stops]);Dependencies Array
typescript// Check useEffect dependencies useEffect(() => { renderRoute(route); }, [route, renderRoute]); // Only re-run when these change
Memory Leaks
Problem: Memory usage increases over time.
Solutions:
Cleanup in useEffect
typescriptuseEffect(() => { const map = initializeMap(); return () => { // Always cleanup map.destroy(); }; }, []);Remove Event Listeners
typescriptuseEffect(() => { const handleResize = () => { map?.resize(); }; window.addEventListener('resize', handleResize); return () => { window.removeEventListener('resize', handleResize); }; }, [map]);
Vue Issues
Map Not Rendering in Vue
Problem: Map doesn't appear in Vue component.
Solutions:
Template Ref
vue<template> <!-- ✅ Correct --> <div ref="mapElement" style="width: 100%; height: 600px;" /> <!-- ❌ Wrong - no ref --> <!-- <div style="width: 100%; height: 600px;" /> --> </template> <script setup lang="ts"> import { ref } from 'vue'; import { useRouteMap } from '@route-optimization/vue'; const mapElement = ref<HTMLDivElement>(); const { isReady } = useRouteMap({ mapElement, apiKey: import.meta.env.VITE_GOOGLE_MAPS_API_KEY, }); </script>Wait for Element
typescriptimport { ref, onMounted } from 'vue'; const mapElement = ref<HTMLDivElement>(); onMounted(() => { // Element is guaranteed to be available const { isReady } = useRouteMap({ mapElement, apiKey: 'YOUR_API_KEY', }); });
Reactivity Issues
Problem: Map doesn't update when data changes.
Solutions:
Use Computed
typescriptimport { computed, watch } from 'vue'; const route = computed(() => ({ stops: props.stops, options: routeOptions.value, })); watch(route, (newRoute) => { renderRoute(newRoute); });Deep Watch
typescriptwatch( () => props.stops, (newStops) => { updateRoute(newStops); }, { deep: true } // Watch nested changes );
Nuxt SSR Issues
Problem: "window is not defined" error in Nuxt.
Solutions:
Use ClientOnly
vue<template> <ClientOnly> <RouteMapComponent /> </ClientOnly> </template>Lazy Import
typescript// nuxt.config.ts export default defineNuxtConfig({ components: [ { path: '~/components', extensions: ['.vue'], }, ], }); // Component const RouteMapComponent = defineAsyncComponent(() => import('./RouteMapComponent.vue'));
TypeScript Issues
Type Errors
Problem: TypeScript shows type errors.
Solutions:
Import Types
typescriptimport type { LatLng, Stop, Route, OptimizationRequest } from '@route-optimization/core';Type Assertions (Use Sparingly)
typescript// ✅ Prefer type guards if (isValidRoute(data)) { processRoute(data); } // ⚠️ Use assertions only when necessary const route = data as Route;Generic Types
typescriptinterface CustomMetadata { orderId: string; priority: 'low' | 'medium' | 'high'; } const stop: Stop<CustomMetadata> = { id: '1', location: { lat: 13.7563, lng: 100.5018 }, metadata: { orderId: 'ORD-123', priority: 'high', }, };
Missing Type Definitions
Problem: "Could not find declaration file" error.
Solutions:
Install Type Definitions
bashnpm install --save-dev @types/google.mapsCreate Declaration File
typescript// types/google-maps.d.ts declare namespace google.maps { class Map { constructor(element: HTMLElement, options?: MapOptions); } interface MapOptions { center?: LatLng; zoom?: number; } }
Optimization Issues
Optimization Fails
Problem: Route optimization returns an error.
Solutions:
Check Request Format
typescriptconst request: OptimizationRequest = { shipments: [ { id: 'shipment-1', // Required deliveryLocation: { // At least one location required latitude: 13.7563, longitude: 100.5018, }, }, ], vehicles: [ { id: 'vehicle-1', // Required startLocation: { // Optional but recommended latitude: 13.7563, longitude: 100.5018, }, }, ], };Validate Coordinates
typescriptfunction isValidLatLng(location: OptimizationLocation): boolean { return ( location.latitude >= -90 && location.latitude <= 90 && location.longitude >= -180 && location.longitude <= 180 ); } // Check all locations const allLocations = [ ...request.shipments.flatMap((s) => [s.pickupLocation, s.deliveryLocation]), ...request.vehicles.flatMap((v) => [v.startLocation, v.endLocation]), ].filter(Boolean); const allValid = allLocations.every(isValidLatLng);Check Time Windows
typescript// Ensure times are in ISO 8601 format const timeWindow = { startTime: '2025-12-12T09:00:00Z', // ✅ Correct // startTime: '09:00', // ❌ Wrong endTime: '2025-12-12T17:00:00Z', };
Slow Optimization
Problem: Route optimization takes too long.
Solutions:
Use RETURN_FAST Mode
typescriptconst request: OptimizationRequest = { shipments: [...], vehicles: [...], searchMode: 'RETURN_FAST', // Faster but may be less optimal };Reduce Problem Size
typescript// Split large requests into smaller batches const batchSize = 50; const batches = []; for (let i = 0; i < shipments.length; i += batchSize) { batches.push(shipments.slice(i, i + batchSize)); } for (const batch of batches) { await optimizer.optimize({ shipments: batch, vehicles: [...], }); }Show Progress
typescriptoptimizer.on('progress', ({ progress, step }) => { console.log(`${Math.round(progress * 100)}% - ${step}`); });
Build Issues
Build Failures
Problem: Build fails with errors.
Solutions:
Clear Cache
bash# npm rm -rf node_modules package-lock.json npm install # Yarn rm -rf node_modules yarn.lock yarn install # pnpm rm -rf node_modules pnpm-lock.yaml pnpm installCheck Node Version
bashnode --version # Should be >= 18 # Use nvm to switch versions nvm use 18TypeScript Configuration
json// tsconfig.json { "compilerOptions": { "target": "ES2020", "module": "ESNext", "moduleResolution": "bundler", "strict": true, "jsx": "react-jsx" // For React } }
Module Resolution Errors
Problem: "Cannot find module" errors.
Solutions:
Check Import Paths
typescript// ✅ Correct import { useRouteMap } from '@route-optimization/react'; // ❌ Wrong import { useRouteMap } from '@route-optimization/core';Verify Package Installation
bashnpm list @route-optimization/reactModule Resolution
json// tsconfig.json { "compilerOptions": { "moduleResolution": "node", // or "bundler" for Vite "esModuleInterop": true, "allowSyntheticDefaultImports": true } }
Runtime Errors
"Cannot read property of undefined"
Problem: Accessing properties on undefined objects.
Solutions:
Optional Chaining
typescript// ✅ Safe const location = stop?.location; const lat = stop?.location?.lat; // ❌ Unsafe const lat = stop.location.lat;Null Checks
typescriptif (map && isReady) { renderRoute(route); }Default Values
typescriptconst stops = route?.stops ?? []; const zoom = config?.zoom ?? 12;
Network Errors
Problem: Network requests fail.
Solutions:
Error Handling
typescripttry { const result = await optimizer.optimize(request); } catch (error) { if (error instanceof Error) { console.error('Optimization failed:', error.message); // Handle specific errors if (error.message.includes('NETWORK_ERROR')) { // Retry or show offline message } } }Timeout Handling
typescriptconst timeoutPromise = new Promise((_, reject) => { setTimeout(() => reject(new Error('Timeout')), 30000); }); const result = await Promise.race([optimizer.optimize(request), timeoutPromise]);
Console Warnings
React Warnings
Problem: "Warning: Can't perform a React state update on an unmounted component".
Solutions:
import { useEffect, useRef } from 'react';
function useIsMounted() {
const isMounted = useRef(true);
useEffect(() => {
return () => {
isMounted.current = false;
};
}, []);
return isMounted;
}
function MapComponent() {
const isMounted = useIsMounted();
const [data, setData] = useState(null);
useEffect(() => {
fetchData().then((result) => {
if (isMounted.current) {
setData(result);
}
});
}, []);
}Vue Warnings
Problem: "Warning: Avoid mutating a prop directly".
Solutions:
// ❌ Wrong
props.stops.push(newStop);
// ✅ Correct
const stops = ref([...props.stops]);
stops.value.push(newStop);
// Or emit event
emit('update:stops', [...props.stops, newStop]);Debugging Tips
Enable Debug Logging
// Set debug flag
const config: RouteCalculatorConfig = {
apiKey: 'YOUR_API_KEY',
debug: true, // Enable debug logging
};Chrome DevTools
- Network Tab: Check API requests
- Console: View errors and logs
- Performance: Profile rendering
- Memory: Check for leaks
React DevTools
// Add displayName for better debugging
const RouteMapComponent = () => { ... };
RouteMapComponent.displayName = 'RouteMapComponent';Vue DevTools
// Use vue-devtools
// Install: https://devtools.vuejs.org/Getting Help
If you're still experiencing issues:
Check Documentation
- Review the relevant guide
- Check the API Reference
Search Issues
- Look for similar issues on GitHub
- Check Stack Overflow
Create an Issue
- Provide a minimal reproduction
- Include error messages
- Share environment details
Community Support
- Ask in GitHub Discussions
- Join our Discord server
Next Steps
- Review Performance optimization
- Explore Customization options
- Check out Examples