I would like to retrieve the distance between two positions. I can get the name but not the distance. I have an error
The following _CastError was thrown building:
Null check operator used on a null value
when I do
print(jsonData);
I get
I/flutter ( 8181): [{nom: CLINIQUE CENTRE, latitude: 37.7586968, longitude: -122.3053474, distance: 0}, {nom: CLINIQUE CHATEAU, latitude: 37.8711583, longitude: -122.336457, distance: 0}, {nom: CLINIQUE ARAFAT, latitude: 37.5206515, longitude: -122.064364, distance: 0}]
this is my model
class Destination {
double lat;
double lng;
String name;
double? distance;
Destination(this.lat, this.lng, this.name, {this.distance});
}
here is what i tried
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:flutter_sorting_location/Utils.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async';
import 'Destinations.dart';
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
double? distance;
List<Destination> destinations = [];
Position? _currentPosition;
Future<List<Destination>> getData() async {
var url = 'http://xxxx/flutter/getlocation.php';
var res = await http.get(Uri.parse(url));
var jsonData = json.decode(res.body);
print(jsonData);
for (var destinationval in jsonData) {
// print(destinationval['nom']);
Destination dests = Destination(
double.parse(destinationval['latitude']),
double.parse(destinationval['longitude']),
destinationval['nom'],
);
destinations.add(dests);
}
// print(destinations);
return destinations;
}
@override
void initState() {
_getCurrentLocation();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Location sorting from current location"),
),
body: FutureBuilder(
future: getData(),
builder: (context, snapshot) {
if (snapshot.hasData) {
final audioList = snapshot.data as List<Destination>;
return ListView.builder(
itemCount: audioList.length,
itemBuilder: (context, index) {
return Card(
margin: EdgeInsets.all(5),
elevation: 5,
child: Padding(
padding: EdgeInsets.all(5),
child: Container(
height: 40,
color: Colors.white,
child: Column(
children: [
Text(audioList[index].name.toString()),
Text(
"${audioList[index].distance!.toStringAsFixed(2)} km"),
],
),
),
),
);
});
} else if (snapshot.hasError) {
// handle error here
return Text('${snapshot.error}');
} else {
return CircularProgressIndicator(); // displays while loading data
}
}),
);
}
// get Current Location
_getCurrentLocation() {
Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.best,
forceAndroidLocationManager: true)
.then((Position position) {
distanceCalculation(position);
setState(() {
_currentPosition = position;
});
}).catchError((e) {
print(e);
});
}
distanceCalculation(Position position) {
for (var d in destinations) {
print(d);
var km = getDistanceFromLatLonInKm(
position.latitude, position.longitude, d.lat, d.lng);
// var m = Geolocator.distanceBetween(position.latitude,position.longitude, d.lat,d.lng);
// d.distance = m/1000;
d.distance = km;
destinations.add(d);
// print(getDistanceFromLatLonInKm(position.latitude,position.longitude, d.lat,d.lng));
}
setState(() {
destinations.sort((a, b) {
// print("a : ${a.distance} b : ${b.distance}");
return a.distance!.compareTo(b.distance!);
});
});
}
}
CodePudding user response:
I just corrected
Text("${audioList[index].distance?.toStringAsFixed(2)} km"),
but i can't get distance . it's show me null
CodePudding user response:
While you are creating instance, it is missing optional distance
field here.
for (var destinationval in jsonData) {
Destination dests = Destination(
double.parse(destinationval['latitude']),
double.parse(destinationval['longitude']),
destinationval['nom'],
distance: double.tryParse(destinationval["distance"])
);
audioList[index].distance
is getting null, while distance
is nullable, it is risky to use !
without null check.
Safer way is checking null 1st and then use !
or provide default value on null case. For string on Text, it can print null
Text("${audioList[index].distance?.toStringAsFixed(2)} km"),
Or just ignore the text build like
if(audioList[index].distance!=null) Text("${audioList[index].distance?.toStringAsFixed(2)} km"),
CodePudding user response:
with
for (var destinationval in jsonData) {
Destination dests = Destination(
double.parse(destinationval['latitude']),
double.parse(destinationval['longitude']),
destinationval['nom'],
distance: double.tryParse(destinationval["distance"])
)
and
if(audioList[index].distance!=null) Text("${audioList[index].distance?.toStringAsFixed(2)} km"),
the screen now displays
type 'Null' is not a subtype of type 'String'
I think the problem lies here since I have to calculate the distance and display it
distanceCalculation(Position position) {
for (var d in destinations) {
var km = getDistanceFromLatLonInKm(
position.latitude, position.longitude, d.lat, d.lng);
d.distance = km;
destinations.add(d);
// print(getDistanceFromLatLonInKm(position.latitude,position.longitude, d.lat,d.lng));
}
setState(() {
destinations.sort((a, b) {
// print("a : ${a.distance} b : ${b.distance}");
return a.distance!.compareTo(b.distance!);
});
});
}