I'm trying to convert an address to coordinates, I get the address using the Google Place API, what I get is a json object like this:
"predictions" : [
{
"description" : "Nueva Galicia 342, Urdiñola, Saltillo, Coah., México",
"matched_substrings" : [
{
"length" : 13,
"offset" : 0
},
{
"length" : 3,
"offset" : 14
}
],
My code is:
import 'dart:convert';
import 'package:http/http.dart';
class Suggestion {
final String placeId;
final String description;
Suggestion(this.placeId, this.description);
@override
String toString() {
return 'Suggestion(description: $description, placeId: $placeId)';
}
}
class PlaceApiProvider {
final client = Client();
PlaceApiProvider(this.sessionToken);
final sessionToken;
final apiKey = 'API KEY';
Future<List<Suggestion>> fetchSuggestions(
String input,
) async {
final request =
'https://maps.googleapis.com/maps/api/place/autocomplete/json?input=$input&types=address&language=es-Es&components=country:mx&key=$apiKey&sessiontoken=$sessionToken';
final response = await client.get(Uri.parse(request));
final requestCoordinates =
'https://maps.googleapis.com/maps/api/geocode/json?address=$address&key=$apiKey';
final responseCoordinates = await client.get(Uri.parse(requestCoordinates));
print(response.body);
print(responseCoordinates.body);
if (response.statusCode == 200) {
final result = json.decode(response.body);
if (result['status'] == 'OK') {
return result['predictions']
.map<Suggestion>((p) => Suggestion(p['place_id'], p['description']))
.toList();
}
if (result['status'] == 'ZERO_RESULTS') {
return [];
}
throw Exception(result['error_message']);
} else {
throw Exception('Failed to fetch suggestion');
}
}
}
I know that I need to get the description from the response, and then use it in the $address of the requestCoordinates, but I don't know how to do it, can someone help on this?
CodePudding user response:
you can use flutter_google_places package provide by flutter community.it give you google places autocomplete widgets. if you need code and explanation then let me know
CodePudding user response:
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 = "AIzaSyDUJ9IM2aSBxfQBozwn4aFt70FDaEGtfu0";
@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?