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