flutter batch http requests - google-maps

I am trying to send multiple http request to the google maps api to get the time taken for a journey. With the code below:
getRouteCoordinates(LatLng sourceCords, LatLng destCords)async{
String url = "https://maps.googleapis.com/maps/api/directions/json?origin=${sourceCords.latitude},${sourceCords.longitude}&destination=${destCords.latitude},${destCords.longitude}&key=$apiKey";
http.Response response = await http.get(url);
Map values = jsonDecode(response.body);
}
So I decide to use this package
[ batching_future ] , but I cant seem to understand how I can use this package to make it work.
I want to do this batch request with destination inputs like
var inputs = [
LatLng(43.721160, 45.394435),
LatLng(23.732322, 78.385142),
LatLng(21.721160, 90.394435),
LatLng(13.732322, 59.385142),
LatLng(47.721160, 80.394435),
LatLng(25.732322, 60.385142),
];
How can I achieve this. Thanks in advance.

The gmaps_multidestination package does the track.
The relevant code to run a batch request for travel times is copy and pasted below:
import 'package:google_maps_webservice/distance.dart';
import 'package:meta/meta.dart';
/// Computes travel times from [myLocation] to [destinations] in batch using
/// Google Distance Matrix API and [apiKey].
///
/// Requires Google Maps API Key, Google Distance Matrix API, and is subject
/// to the limitations of the Matrix API (such as maximum destinations per
/// request)
Future<Map<Location, Duration>> batchTravelTimes(
{#required Location myLocation,
#required List<Location> destinations,
#required String apiKey}) async =>
(await GoogleDistanceMatrix(apiKey: apiKey)
.distanceWithLocation([myLocation], destinations))
.results
.expand((row) => row.elements)
.toList()
.asMap()
.map((i, location) => MapEntry(
destinations[i], Duration(seconds: location.duration.value)));
The code to connect the above batching_future is:
/// Computes travel times from `O` to `[D1,D2,D3]` in batch.
/// Requires Google Maps API Key, Google Distance Matrix API, and is subject
/// to the limitations of the Matrix API (such as maximum destinations per
/// request)
import 'package:batching_future/batching_future.dart';
import 'package:google_maps_webservice/distance.dart';
import 'package:meta/meta.dart';
typedef MyLocationProvider = Future<Location> Function();
BatchingFutureProvider<Location, Duration> batchingFutureTravelTime(
{#required MyLocationProvider myLocationProvider,
#required String apiKey}) =>
createBatcher(
(destinations) async => (await batchTravelTimes(
apiKey: apiKey,
myLocation: await myLocationProvider(),
destinations: destinations))
.values
.toList(),
maxBatchSize: 20,
maxWaitDuration: Duration(milliseconds: 200),
);

Related

Flutter json data from http.get is returning old database values in App and Latest values in Browser

final String url = "https://stsrefiners.com/wp-content/plugins/calculator/templates/mobilefixedval.php";
List data;
void initState()
{
super.initState();
//this.getJsonData();
Timer.periodic(Duration(seconds: 10), (timer) {
this.getJsonData();
});
}
Future<String> getJsonData() async
{
var response = await http.get(
Uri.encodeFull(url),
headers: {"Accept":"application/json"}
);
setState(() {
var convertDataToJson = json.decode(response.body);
data = convertDataToJson;
print(data);
_isLoading = true;
});
return "Success";
}
Data is fetched using the getJsonData Fucntion and in URL the data is fetched using the MYSQL database using mysqli method when I open the URL in browser it returns the latest values but when I fetch the data in application both in android and IOS it returns the old.
The data is not updating at run time
I'm also facing the same issue due to the Network cache setting in the browser.
Workaround solution
I added random URL query value in API call..
For Example:
my actual API URL
www.xyz.com?id=1
I changed this into
www.xyz.com?id=1&r=somerandomnumber (every call)

How to Search for Addresses using Postal Codes

I am using the google_maps_webservice package to fetch geocoding data from Google Maps Web Services.
I want to get the list of addresses, attached to a postal code.
Here's a small snippet of code that demonstrates that:
import 'package:google_maps_webservice/places.dart';
final _places =
GoogleMapsPlaces(apiKey: '<API-Key>');
void main() async {
// This is a valid British postal code.
final postalCode = 'WC2N 5DU';
final response = await _places.autocomplete(
postalCode,
components: [
Component(Component.postalCode, postalCode),
Component(Component.country, 'GB'),
],
location: Location(51.50721, -0.12827),
);
if (response.isOkay) {
for (Prediction prediction in response.predictions) {
print(prediction.description);
}
} else {
print(response.status);
}
}
I get an INVALID_REQUEST status message.
From the Google Maps Geocoding docs
"INVALID_REQUEST" generally indicates that the query (address, components or latlng) is missing.
The components, latlng arguments are passed to the API, but I need it to return the address, associated with the postal code.

Get json Data from Rapid API in Flutter (Dart)

I managed to load the data from a Json File which is local on my Flutter Project. I also was able to fetch Data from the Internet, if the API Url was like:
https://[API-Server][parameter1:xy][parameter2:abc][API-KEY:lasgoewrijeowfjsdfdfiia]
I archieved that with this code sample:
Future<String> _loadStringFixtures() async {
return await rootBundle.loadString('assets/fixtures.json');
}
Future loadFixtures() async {
String jsonString = await _loadStringFixtures();
final jsonResponse = json.decode(jsonString);
FixturesAPI value = new FixturesAPI.fromJson(jsonResponse);
return value;
}
So far so good...
But now I am facing a problem with the API Provider RapidAPI
You can find the documentation etc. here:
https://rapidapi.com/api-sports/api/api-football/endpoints
As you can see they give some code snippets to connect to their API.
There are some for C, C#, Java, Python etc. You can look into all of them with the link above.
Sadly there is no example for Flutter.
And I do not see a way to adapt these examples.
Normally you can paste your API Key directly into the URL, but this seems not possible here? Or maybe it is?
Does Flutter also have other possibilities to receive data from an API besides the one I did?
Thank you so much in advance for your help!
It's possible to with http package and very easy. You can see in this example below...
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
class APIService {
// API key
static const _api_key = <YOU-API-KEY-HERE>;
// Base API url
static const String _baseUrl = "api-football-beta.p.rapidapi.com";
// Base headers for Response url
static const Map<String, String> _headers = {
"content-type": "application/json",
"x-rapidapi-host": "api-football-beta.p.rapidapi.com",
"x-rapidapi-key": _api_key,
};
// Base API request to get response
Future<dynamic> get({
#required String endpoint,
#required Map<String, String> query,
}) async {
Uri uri = Uri.https(_baseUrl, endpoint, query);
final response = await http.get(uri, headers: _headers);
if (response.statusCode == 200) {
// If server returns an OK response, parse the JSON.
return json.decode(response.body);
} else {
// If that response was not OK, throw an error.
throw Exception('Failed to load json data');
}
}
}
Then get you request:
//....
APIService apiService = APIService();
// You future
Future future;
//in the initState() or use it how you want...
future = apiService.get(endpoint:'/fixtures', query:{"live": "all"});
//....
Yes it possible in flutter. Use the Dio Package in flutter which is a powerful Http client. Using dio you can set interceptors to add api key to url so you don't have to append it in every request. Setting interceptors will help you.

Flutter - using an API key

I'm making an app that grabs cryptocurrency JSON data from the public v1 Api but support for this will soon be dropped, meaning that I'll have to migrate the the more powerful professional v1 Api.
The only issue is, I don't know how to implement the use of the new Api key thats required as I parse the JSON data.
I'm using a heavily modified version of this git repo to program the app, but all basic functionality is based here.
All I need is guidance on what I need to add to this file to display the new professional v1 Api, any comments or ideas are appreciated. Thanks
This the the crypto_data_prod.dart file where I would have to change my code for use with the key.
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:fluttercrypto/data/crypto_data.dart';
class ProdCryptoRepository implements CryptoRepository {
String cryptoUrl = "https://api.coinmarketcap.com/v1/ticker/?limit=50";
#override
Future<List<Crypto>> fetchCurrencies() async {
// TODO: implement fetchCurrencies
http.Response response = await http.get(cryptoUrl);
final List responseBody = JSON.decode(response.body);
final statusCode = response.statusCode;
if (statusCode != 200 || responseBody == null) {
throw new FetchDataException(
"An error ocurred : [Status Code : $statusCode]");
}
return responseBody.map((c) => new Crypto.fromMap(c)).toList();
}
}
Try to change http.Response response = await http.get(cryptoUrl); to
http.Response response = await http.get(cryptoUrl,
headers: {"X-CMC_PRO_API_KEY": "cab79c7b-52e9-4e4b-94fc-b0f32da14799"});
For more info check this link.

Salesforce Apex Google Drive API is creating new file with mimeType "application/json"

Trying to create a function in apex that will create Google Drive folders when creating a new record in Salesforce.
I have managed to authenticate and handle GET requests just fine. My issue is regarding the POST requests. The code below should create a folder with the label provided in the "title" parameter. The script executes and instead creates an extension-less file without a label.
public void getDriveFiles(HttpResponse authResponse) {
http h = new Http();
Httprequest req = new HttpRequest();
HttpResponse res = new HttpResponse();
Map<String, Object> responseObject = (Map<String, Object>) JSON.deserializeUntyped(authResponse.getBody());
req.setEndpoint('https://www.googleapis.com/upload/drive/v2/files');
req.setMethod('POST');
req.setHeader('Content-type', 'application/json');
req.setHeader('Authorization', 'Bearer '+responseObject.get('access_token'));
String jsonData = '{"title":"NewFolder", "mimeType":"application/vnd.google-apps.folder"}';
req.setBody(jsonData);
res = h.send(req);
system.debug('Response ='+ res.getBody() +' '+ res.getStatusCode());
}
I have a feeling it's my request body but I have no idea what to do to fix it.
You've used the wrong endpoint. Instead of the file endpoint, you're posting to the content endpoint.
So
req.setEndpoint('https://www.googleapis.com/upload/drive/v2/files');
should be (for the v2 API)
req.setEndpoint('https://www.googleapis.com/drive/v2/files');
or (for the v3 API)
req.setEndpoint('https://www.googleapis.com/drive/v3/files');
If you use v3 (which you probably should), your json should change thus
String jsonData = '{"name":"NewFolder", "mimeType":"application/vnd.google-apps.folder"}';