The intent is to have the page load and show in the Google Map the current location as per the GPS of the device.
What is wrong in the following code? It appears it doesn't want to await the location and return "Null check operator used on a null value".
I am having trouble finding the answer and would appreciate some assistance.
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:location/location.dart';
class FindSomeonePage extends StatefulWidget {
const FindSomeonePage({Key? key}) : super(key: key);
@override
State<FindSomeonePage> createState() => _FindSomeonePageState();
}
class _FindSomeonePageState extends State<FindSomeonePage> {
LatLng? _initialLocation;
late GoogleMapController mapController;
@override
void initState() {
super.initState();
_setInitialLocation();
}
_setInitialLocation() async {
LocationData? currentLocation = await getCurrentLocation();
if (currentLocation != null) {
setState(() {
_initialLocation =
LatLng(currentLocation.latitude!, currentLocation.longitude!);
});
}
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Stack(
children: [
GoogleMap(
//LatLng(-15.4630239974464, 28.363397732282127)
initialCameraPosition: CameraPosition(
target: _initialLocation!,
zoom: 15.0,
),
onMapCreated: (controller) {
mapController = controller;
},
),
],
),
),
);
}
}
Future<LocationData?> getCurrentLocation() async {
Location location = new Location();
bool _serviceEnabled;
PermissionStatus _permissionGranted;
_serviceEnabled = await location.serviceEnabled();
if (!_serviceEnabled) {
_serviceEnabled = await location.requestService();
if (!_serviceEnabled) {
return null;
}
}
_permissionGranted = await location.hasPermission();
if (_permissionGranted == PermissionStatus.denied) {
_permissionGranted = await location.requestPermission();
if (_permissionGranted != PermissionStatus.granted) {
return null;
}
}
return await location.getLocation();
}
You are getting that error because the _initialLocation
is initially null and you are using it in the body of your widget without checking if the value is null and without awaiting the result of your getCurrentLocation()
.
To solve this, you need to show loading spinner to your widget while fetching the currentLocation
.
first, intialize a _isLoading
variable:
bool _isLoading = false;
Then your _setInitialLocation
should be:
_setInitialLocation() async {
_isLoading = true;
LocationData? currentLocation = await getCurrentLocation();
if (currentLocation != null) {
_initialLocation =
LatLng(currentLocation.latitude!, currentLocation.longitude!);
}
///this rebuilds your widget whether or not the fetch location is successful
///It is then your responsibility to show error to your widget when error occur.
setState(() {
_isLoading = false;
});
}
And the body of your widget should be:
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: _isLoading ? CircularProgressIndicator() : Stack(
children: [
if(_initialLocation != null)...[
GoogleMap(
//LatLng(-15.4630239974464, 28.363397732282127)
initialCameraPosition: CameraPosition(
target: _initialLocation!,
zoom: 15.0,
),
onMapCreated: (controller) {
mapController = controller;
},
),
]
],
),
),
);
}
}