How to call Future method before StreamBuilder on Flutter? - 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??

Related

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;
}

Assign Future<var> to var

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 } );

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 get latitude and longitude in flutter

I can figure out how to get the user's latitude and longitude together, but need to get them individually to utilise the Geolocator().distanceBetween function from the Geolocator package. My code below keeps getting the error:
Unhandled Exception: NoSuchMethodError: The getter 'latitude' was called on null.
Receiver: null
Tried calling: latitude
Future<Position> getLocation() async {
var currentLocation;
try {
currentLocation = await geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.best);
} catch (e) {
currentLocation = null;
}
return currentLocation;
}
void calculateDistance() async {
getLocation().then((position) {
userLocation = position;
});
final double myPositionLat = userLocation.latitude;
final double myPositionLong = userLocation.longitude;
final double TPLat = 51.5148731;
final double TPLong = -0.1923663;
final distanceInMetres = await Geolocator().distanceBetween(myPositionLat, myPositionLong, TPLat, TPLong)/1000;
print(distanceInMetres);
}
Try this :
void calculateDistance() async {
getLocation().then((position) {
userLocation = position;
final double myPositionLat = userLocation.latitude;
final double myPositionLong = userLocation.longitude;
final double TPLat = 51.5148731;
final double TPLong = -0.1923663;
final distanceInMetres = await Geolocator().distanceBetween(myPositionLat, myPositionLong, TPLat, TPLong)/1000;
print(distanceInMetres);
});
}
or another way of doing this is :
void calculateDistance() async {
userLocation = await getLocation();
final double myPositionLat = userLocation.latitude;
final double myPositionLong = userLocation.longitude;
final double TPLat = 51.5148731;
final double TPLong = -0.1923663;
final distanceInMetres = await Geolocator().distanceBetween(myPositionLat, myPositionLong, TPLat, TPLong)/1000;
print(distanceInMetres);
}

check it current location is near to other locations

I have list of Latlng that contains on list of places lat&lng
and I want check my current location is near of any of these places by 1 kilo
static locationListen() async {
List<LatLng> savedPlace = [
LatLng(12.333,-344.2222),
LatLng(1.333,-14.2222),
LatLng(2.333,-24.2222),
];
var locationOptions =
LocationOptions(accuracy: LocationAccuracy.high, distanceFilter: 10);
Geolocator().getPositionStream(locationOptions).listen(
(Position position) {
LatLng currentLatlng = LatLng(position.latitude,position.longitude);
//check this if is this currentLatlng near by 1 kilo from
// any of those places savedPlace
},
);
}
I see you're using Geolocator plugin:
Take a try like that:
double distanceInMeters = await Geolocator().distanceBetween(lat1, lng1, lat2, lng2);
you can use plugin call latlong 0.6.1
dependencies:
latlong: ^0.6.1
import 'package:latlong/latlong.dart';
and try it
Geolocator().getPositionStream(locationOptions).listen( (Position position) {
LatLng currentLatlng = LatLng(position.latitude,position.longitude);
savedPlace.forEach((savedlatlong) {
int km = distance.as(LengthUnit.Kilometer,currentLatlng,savedlatlong);
// do whatever you wanna do with km
});
},);