Home > Blockchain >  flutter_google_places Null Safety Issue
flutter_google_places Null Safety Issue

Time:02-17

I implement the flutter_google_place package, but in the Flutter version that I'm using (2.10.1) the null safety version is causing me some issue. The code is this:

class SearchButton extends StatefulWidget {
  const SearchButton({Key? key}) : super(key: key);

  @override
  State<SearchButton> createState() => _SearchButtonState();
}

class _SearchButtonState extends State<SearchButton> {
  final _destinationController = TextEditingController();
  final ApiKey = "XYZ";

  @override
  void dispose() {
    _destinationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final newLocation = Provider.of<ClientRequest>(context);
    final sessionToken = const Uuid().v4();
    Mode _mode = Mode.overlay;

    void one rror(PlacesAutocompleteResponse response) {
      SnackBar(
        content: Text(response.errorMessage),
      );
    }

    Future<void> displayPrediction(Prediction p) async {
      if (p != null) {
        GoogleMapsPlaces _places = GoogleMapsPlaces(
          apiKey: ApiKey,
          apiHeaders: await const GoogleApiHeaders().getHeaders(),
        );
        PlacesDetailsResponse detail =
            await _places.getDetailsByPlaceId(p.placeId);
        final lat = detail.result.geometry?.location.lat;
        final lng = detail.result.geometry?.location.lng;
        SnackBar(
          content: Text("${p.description} - $lat/$lng"),
        );
        print(detail);
      }
    }

    Future<void> _handlePressButton() async {
      Prediction p = await PlacesAutocomplete.show(
        context: context,
        apiKey: ApiKey,
        one rror: one rror,
        mode: _mode,
        language: "fr",
        decoration: InputDecoration(
          hintText: 'Search',
          focusedBorder: OutlineInputBorder(
            borderRadius: BorderRadius.circular(20),
            borderSide: const BorderSide(
              color: Colors.white,
            ),
          ),
        ),
        components: [Component(Component.country, "mx")],
      );

      displayPrediction(p);
    }

    return MaterialButton(
      onPressed: _handlePressButton,
      child: Container(
        padding: const EdgeInsets.only(left: 3, right: 3),
        child: Container(
          decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(20),
              boxShadow: const [
                BoxShadow(
                  color: Colors.grey,
                  spreadRadius: 1,
                  blurRadius: 3,
                  offset: Offset(0, 3),
                ),
              ]),
          child: TextField(
            controller: _destinationController,
            decoration: InputDecoration(
              enabled: false,
              prefixIcon: const Icon(Icons.search),
              filled: true,
              fillColor: const Color(0xffEDEDED),
              hintText: 'Ingresa una nueva dirección',
              contentPadding:
                  const EdgeInsets.only(left: 14.0, bottom: 8.0, top: 8.0),
              disabledBorder: OutlineInputBorder(
                borderSide: const BorderSide(color: Colors.white),
                borderRadius: BorderRadius.circular(20),
              ),
              border: const OutlineInputBorder(),
            ),
          ),
        ),
      ),
    );
  }
}

The error are in: response.errorMessage -> The argument type 'String?' can't be assigned to the parameter type 'String' p.placeId -> The argument type 'String?' can't be assigned to the parameter type 'String'. await PlacesAutocomplete.show -> A value of type 'Prediction?' can't be assigned to a variable of type 'Prediction'. Try changing the type of the variable, or casting the right-hand type to 'Prediction'.

Any clue how to fix this?

CodePudding user response:

Basically you should write Text(response.errorMessage!), Whenever you get such error where X? can not be assigned to X, just add an exclaimation mark at the end.

CodePudding user response:

I think your IDE should warn you about where to fix it but from what I understand with the messages You need to change the three values.

Check the commented code below.

class SearchButton extends StatefulWidget {
  const SearchButton({Key? key}) : super(key: key);

  @override
  State<SearchButton> createState() => _SearchButtonState();
}

class _SearchButtonState extends State<SearchButton> {
  final _destinationController = TextEditingController();
  final ApiKey = "XYZ";

  @override
  void dispose() {
    _destinationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final newLocation = Provider.of<ClientRequest>(context);
    final sessionToken = const Uuid().v4();
    Mode _mode = Mode.overlay;

    void one rror(PlacesAutocompleteResponse response) {
      SnackBar(
        content: Text(response.errorMessage),
      );
    }

    /// This prediction value is expected to be a nullable type, so you 
    /// should make it nullable
    Future<void> displayPrediction(Prediction? p) async {
      if (p != null) {
        GoogleMapsPlaces _places = GoogleMapsPlaces(
          apiKey: ApiKey,
          apiHeaders: await const GoogleApiHeaders().getHeaders(),
        );
        /// p.placeId here is getting the value from p variable and since it
        /// might be null but it is checked to be not, we can put an exclamation mark
        PlacesDetailsResponse detail =
            await _places.getDetailsByPlaceId(p!.placeId);
        final lat = detail.result.geometry?.location.lat;
        final lng = detail.result.geometry?.location.lng;
        SnackBar(
          content: Text("${p.description} - $lat/$lng"),
        );
        print(detail);
      }
    }

    Future<void> _handlePressButton() async {
      /// This value here can be null, so it should be assigned as nullable
      /// I would also suggest to use final
      final p = await PlacesAutocomplete.show(
        context: context,
        apiKey: ApiKey,
        one rror: one rror,
        mode: _mode,
        language: "fr",
        decoration: InputDecoration(
          hintText: 'Search',
          focusedBorder: OutlineInputBorder(
            borderRadius: BorderRadius.circular(20),
            borderSide: const BorderSide(
              color: Colors.white,
            ),
          ),
        ),
        components: [Component(Component.country, "mx")],
      );

      displayPrediction(p);
    }

    return MaterialButton(
      onPressed: _handlePressButton,
      child: Container(
        padding: const EdgeInsets.only(left: 3, right: 3),
        child: Container(
          decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(20),
              boxShadow: const [
                BoxShadow(
                  color: Colors.grey,
                  spreadRadius: 1,
                  blurRadius: 3,
                  offset: Offset(0, 3),
                ),
              ]),
          child: TextField(
            controller: _destinationController,
            decoration: InputDecoration(
              enabled: false,
              prefixIcon: const Icon(Icons.search),
              filled: true,
              fillColor: const Color(0xffEDEDED),
              hintText: 'Ingresa una nueva dirección',
              contentPadding:
                  const EdgeInsets.only(left: 14.0, bottom: 8.0, top: 8.0),
              disabledBorder: OutlineInputBorder(
                borderSide: const BorderSide(color: Colors.white),
                borderRadius: BorderRadius.circular(20),
              ),
              border: const OutlineInputBorder(),
            ),
          ),
        ),
      ),
    );
  }
}
  • Related