Assign Future<var> to var - flutter

I have some code written in dart where I use the provider package to update the location of a pin on a map. What I would like it to do is have the initial location be equal to the user's current position and then if they drag the pin it will be updated to wherever the pin is dropped.
My problem is that the initial location variable needs to Future<LatLng>, however, when I update the location it ends up being just LatLng and I cannot assign it to the _location variable.
class LocationProvider with ChangeNotifier {
Future<LatLng> _location = LocationService().getLocation();
// Error here, wants it to be Future<LatLng>
LatLng get location => _location;
void calculateNewLocation(oldLocation, zoom, offset) {
var newPoint = const Epsg3857().latLngToPoint(oldLocation, zoom) +
CustomPoint(offset.dx, offset.dy);
LatLng? newLocation = const Epsg3857().pointToLatLng(newPoint, zoom);
// Error here again for the same reason
_location = newLocation ?? _location;
notifyListeners();
}
}
How do I make it so that I can assign both of these values to _location?

You can simply have a method for that in provider file
class LocationProvider with ChangeNotifier {
LatLng? _location;
LatLng? get location => _location;
Future<void> initializeLocation() async {
_location = await LocationService().getLocation();
notifyListeners();
}
void calculateNewLocation(oldLocation, zoom, offset) {
var newPoint = const Epsg3857().latLngToPoint(oldLocation, zoom) +
CustomPoint(offset.dx, offset.dy);
LatLng? newLocation = const Epsg3857().pointToLatLng(newPoint, zoom);
_location = newLocation ?? _location;
notifyListeners();
}
}
Then, you'll have to call initializeLocation when you want it to be initialized, like:
Future<void>? _myFuture;
final _provider = Provider.of<LocationProvider>(listen: false);
_myFuture = _provider.initializeLocation();
and then in FutureBuilder, provide _myFuture in future
PS: ? can be excluded if you're not using dart in null safe mode

Based on your code,
LocationService().getLocation() returns a future, so you have to either await/async or use then().
try these
Future<LatLng> _location = LocationService().getLocation();
LatLng get location = await _location; // put this in a separate method with async keyword
or
LocationService().getLocation().then((value) { location = value } );

Related

The instance member 'currentPosition' can't be accessed in an initializer. with geolocator when trying to get position

I've been trying to get the user's current location on Android, but I'm struggling to get it to work because of an instance initialization error. I'm using the following code right now to get the user's latitude and longitude into a variable.
Position? currentPosition;
final Geolocator geolocator = Geolocator();
void _getCurrentLocation() {
Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.best)
.then((Position position) {
setState(() {
currentPosition = position;
});
}).catchError((e) {
print(e);
});
}
late GoogleMapController myMapController;
final Set<Marker> _markers = {};
static final LatLng _mainLocation =
LatLng(currentPosition!.latitude, currentPosition!.longitude);
I've tried using Future and different ways of formatting the function, but I run into an issue one way or another. Any particular way I can get this to work? Thank you!
You can use
final Set<Marker> _markers = {};
late final LatLng _mainLocation =
LatLng(currentPosition!.latitude, currentPosition!.longitude);
Define static to currentPosition, Thanks.

How do i initialize the non nullable instance in flutter

`
class Location{
late double lat;
late double lon;
void getLocation( ) async{
Position position = await _determinePosition();
lat=position.latitude;
lon=position.longitude;
}
Future<Position> _determinePosition() async {
LocationPermission permission;
permission=await Geolocator.checkPermission();
if(permission==LocationPermission.denied){
permission=await Geolocator.requestPermission();
if(permission==LocationPermission.denied){
return Future.error('Permission Denied');
}
}
return await Geolocator.getCurrentPosition();
}
}
`How to initialize the value of varibale lat and lon in this? ,
i have done everything in my reach, but it always ends with error 'Non-nullable instance field 'lon' must be initialized. (Documentation) Try adding an initializer expression, or a generative constructor that initializes it, or mark it 'late'.
and if i add late than it show runtime error on my device,that late variable should be initialized.
double? lat;
double? lng;
///get location
void getLocation(pr) async {
await [
Permission.location,
].request();
if (await Permission.locationWhenInUse.serviceStatus.isEnabled) {
print('no');
}
Position position = await Geolocator.getCurrentPosition( desiredAccuracy: LocationAccuracy.high);
lat = position.latitude;
lng = position.longitude;
}

Flutter - <asynchronous suspension> with geocoder package

I need to get the city name from Longitude and Latitude.
I do not found a single package to do that, so I use location package to get Long and Lat and used geocoder to get the city name.
But I keep have this error and have no result :
[ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: PlatformException(failed, Failed, null, null)
and this one after it on the console: < asynchronous suspension >
Here is my code :
class _ProfileScreenState extends State<ExploreScreen> {
dynamic currentLocation;
double userLongitude;
double userLatitude;
Coordinates coordinates;
var addresses;
var first;
#override
initState() {
super.initState();
_getCurrentLongAndLat();
_getCurrentPosition(userLatitude, userLatitude);
}
Future _getCurrentLongAndLat() async {
currentLocation = LocationData;
var error;
var location = new Location();
try {
currentLocation = await location.getLocation();
userLatitude = currentLocation.latitude;
userLongitude = currentLocation.longitude;
print('$userLatitude $userLatitude');
} on PlatformException catch (e) {
if (e.code == 'PERMISSION_DENIED') {
error = 'Permission denied';
}
currentLocation = null;
}
}
Future _getCurrentPosition(double long, double lat) async {
coordinates = new Coordinates(userLatitude, userLongitude);
addresses = await Geocoder.local.findAddressesFromCoordinates(coordinates);
print(addresses.first);
}
}
I realized flutter packages geolocator and location conflict with each other sometimes.
Try using geolocator to get your current position:
Future _getCurrentPosition() async {
Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high).then((Position position) {
setState(() {
_currentPosition = position;
userLongitude = position.longitude;
userLatitude = position.latitude;
});
});
}
It is a Future, so you can use await to really wait for results and after that call the getAddress function with the userLat and userLng.

How to call Future method before StreamBuilder on Flutter?

I am trying to get the current user position before get the stream data using that info. So using Flutter 1.17.5 and geolocator: ^5.3.2+2 I am getting the Positionusing the follow util class
class LocationProvider {
Future<Position> getPosition() async {
Position position = await Geolocator()
.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
return position;
}
}
then I have to pass the info to bloc in order to retreive the Stream data with the marker
Widget _getAllProducts(ProductBloc productBloc, LocationProvider locationProvider) async{
Position position = locationProvider.getPosition();
var longitude = position.longitude;
var latitude = position.latitude;
int meter = 50;
productBloc.allByRange(meter, latitude, longitude);
return StreamBuilder(
stream: productBloc.productsByRangeStream,
How ever I got this message
A value of type 'StreamBuilder<List<ProductModel>>' can't be returned from method '_getAllProducts' because it has a return type of 'Widget'
Edit 1
class ProductBloc {
Stream<List<ProductModel>> get productsByRangeStream =>
_allByRangeProductsController.stream;
void allByRange(double range, double lat, double lon) async {
final products = await _productFirebaseService.allByRange(range, lat, lon);
_allByRangeProductsController.sink.add(products);
}
}
How can I fix it??

GPS off message, and continous location update flutter

i made an app which uses the geolocator package to check for GPS and get the location of the user, and i use the provider package to handle the state. The problem is, when the GPS is switched off, a red screen appears that says the latitude was null, i would like to implement a screen to tell the user to switch on the GPS, and update the location accordingly.
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:geolocator/geolocator.dart';
import 'package:latlong/latlong.dart';
class MapState with ChangeNotifier {
bool locationServiceActive = true;
MapController _mapController;
MapController get mapController => _mapController;
static var _initialPosition;
var _lastPosition = _initialPosition;
LatLng get initialPosition => _initialPosition;
LatLng get lastPosition => _lastPosition;
MapState(){
checkGPS();
_getUserLocation();
}
checkGPS() async{
bool conn = await Geolocator().isLocationServiceEnabled();
if(conn == false){
locationServiceActive = false;
} else {
locationServiceActive = true;
}
notifyListeners();
}
void _getUserLocation() async{
Position position = await Geolocator().getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
print("/////////////////////////////////////////////////////////////////////////////////position");
print(position);
_initialPosition = LatLng(position.latitude, position.longitude);
notifyListeners();
}
}
update:-
i changed my _getUserLocation function to a stream, which works much better if the user switched on or off the gps (and it uses the last known location if the gps is off)... but it doesn't print the statement in the terminal if the position is null which is weird, only when there is lat and lng!!!
here is the modification i made...
void _getUserLocation() async{
Position position = await Geolocator().getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
var geolocator = Geolocator();
var locationOptions = LocationOptions(accuracy: LocationAccuracy.high, distanceFilter: 10);
StreamSubscription<Position> positionStream = geolocator.getPositionStream(locationOptions).listen(
(Position position) {
print("/////////////////////////////////////////////////////////////////////////// position");
print(position == null ? 'Unknown' : position.latitude.toString() + ', ' + position.longitude.toString());
});
_initialPosition = LatLng(position.latitude, position.longitude);
notifyListeners();
}
If you want to notify the user about the GPS, you can use something like this
#override
void initState() {
super.initState();
initPlatformState();
location.onLocationChanged.listen((result) {
currentLocation = result;
// your code
});
});
}
void initPlatformState() async {
LocationData currentLocation;
try {
currentLocation = await location.getLocation();
error = "";
} on PlatformException catch (e) {
if (e.code == 'PERMISSION_DENIED')
error = 'Permission Denied';
else if (e.code == 'PERMISSION_DENIED_NEVER_ASK')
error =
'Permission denied - please ask the user to enable it from the app settings';
currentLocation = null;
}
setState(() {
currentLocation = currentLocation;
});
}
Here, you are listening to the location stream if enabled. In case it is not then it throws an error. The package being used here is location