From what you've described, it sounds like the crash might be due to updating the markers in the GoogleMapsScreen widget while the widget itself is being built or rendered. This can happen if widget.markers is updated and then re-rendered, leading to inconsistencies in the widget's state. Here are a few steps and improvements to help troubleshoot and potentially resolve this issue:
Set Initial State for Markers: When GoogleMapsScreen is initialized, ensure the markers Set has a default value to avoid any unexpected nulls. Additionally, it might be useful to explicitly update the markers with setState when the markers are updated.
Add Error Handling for API Responses: Ensure that the response data from getBranchesAPI is well-structured and valid before proceeding to create markers. Sometimes, malformed data can lead to unexpected issues without clear error messages.
Handle Markers State with a Key: Add a unique key to GoogleMapsScreen to force the widget to rebuild properly when the markers set updates.
Here are the adjusted sections of your code with these suggestions:
Modify GoogleMapsScreen to Ensure Proper Marker State Handling Use widget.markers with a unique key to force rebuilds and set a default position if the markers are empty.
class GoogleMapsScreen extends StatefulWidget { final Set markers; GoogleMapsScreen({super.key, required this.markers});
@override State createState() => _GoogleMapsScreenState(); }
class _GoogleMapsScreenState extends State {
@override Widget build(BuildContext context) { return GoogleMap( initialCameraPosition: CameraPosition( target: widget.markers.isNotEmpty ? widget.markers.first.position : LatLng(33.8938, 35.5018), // Default location if no markers zoom: 10, // Adjust zoom level as needed ), markers: widget.markers, key: ValueKey(widget.markers), // Use ValueKey to force rebuild on marker change ); } }
Update prepareMarkers in MapViewModel to Verify Marker Data Check that each branch has valid coordinates before adding a marker to avoid crashes from null or invalid data.
void prepareMarkers() { markers = branches.where((branch) => branch.latitude != null && branch.longitude != null).map((branch) { return Marker( markerId: MarkerId(branch.id ?? ""), position: LatLng(branch.latitude ?? 0.0, branch.longitude ?? 0.0), infoWindow: InfoWindow( title: branch.englishBranchName ?? "No Name", snippet: branch.phoneNumber ?? "No Phone", ), ); }).toSet(); setMapLoading(false); }
Add Debugging to Track Errors Add debugging lines in getBranchesAPI to capture and log unexpected issues that might not be obvious otherwise.
Future getBranchesAPI({ required Function(String?) onError}) async { setMapLoading(true); try { var response = await repo.getBranches( pageNumber: MapConstants.pageNumber, pageSize: MapConstants.pageSize, body: {}, ); response.when( success: (NetworkBaseModel response) async { if (response.isSuccess == true) { branches = response.data; prepareMarkers(); } else { onError("Failed to load data"); } }, failure: (NetworkExceptions error) { onError(error.message); setMapLoading(false); }, ); } catch (e) { onError("An unexpected error occurred: $e"); setMapLoading(false); } }
Check Markers in the Consumer Use the Consumer to ensure viewModel.markers is not empty before displaying the map:
Expanded( child: Consumer( builder: (context, viewModel, child) { if (viewModel.isMapLoading) { return Center(child: CircularProgressIndicator()); } else if (viewModel.markers.isEmpty) { return Center(child: Text("No locations available")); } else { return GoogleMapsScreen(markers: viewModel.markers); } }, ),
) This approach will help track down any issues and ensure that GoogleMapsScreen has consistent and valid data when rendering markers.