Home > Mobile >  Null check operator used on a null value in my Future to get List object
Null check operator used on a null value in my Future to get List object

Time:08-14

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!);
      });
    });
  }
  • Related