Cast Error during HTTP Post Request to Google Route API, - flutter

This is the first time I am trying to use an HTTP Rest API with Post request, I am trying to use google Route API to compute direction, I follow the body from the google documentation however I keep getting this error
_CastError
Exception has occurred.
_CastError (type '_Map<String, Map<String, Map<String, double>>>' is not a subtype of type 'String' in type cast)
This is the first time I am trying a post request so I have no idea what is wrong
here' the code I use
import 'dart:async';
import 'dart:ffi';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'package:flutter_polyline_points/flutter_polyline_points.dart';
import 'dart:convert' as convert;
class RouteAPI {
final String key = 'API_KEY_HERE';
Future<Void> getRoute() async {
final String Url =
'https://routes.googleapis.com/directions/v2:computeRoutes?KEY=$key';
var response = await http.post(Uri.parse(Url), body: {
"origin": {
"location": {
"latLng": {
"latitude": -6.2425120808113315,
"longitude": 106.85152720596324
}
},
},
"destination": {
"location": {
"latLng": {
"latitude": -6.2425120808113315,
"longitude": 106.85152720596324
}
},
},
"intermediates": {
"location": {
"latLng": {
"latitude": -6.178359098658539,
"longitude": 106.79219133887105
}
},
},
"travelMode": "DRIVE",
"routingPreference": "TRAFFIC_AWARE",
"polylineQuality": "HIGH_QUALITY",
"polylineEncoding": "ENCODED_POLYLINE",
//"departureTime": "",
"computeAlternativeRoutes": "FALSE",
"routeModifiers": {
"avoidTolls": false,
"avoidHighways": false,
"avoidFerries": false
},
"languageCode": "en-US",
"units": "IMPERIAL"
});
var json = convert.jsonDecode(response.body);
print(json.toString());
return json;
}
}
I tried to send a post body to request an encoded polyline from google route API

Don't include API keys directly in your project, use environment variables, once someone has your API key, this can end bad with a lot of debt. Make sure you reset your key.
flutter_dotenv.
You also need to include your API key in your request header, from what I read. Compute a route docs
You're receiving a type error because you're not encoding your body JSON into a string.
convert.jsonEncode({"example": "example"})
You then aren't setting the content type header to let the API know what kind of data you're sending, and the API Key, along with the field mask header.
headers: {
"Content-Type": "application/json",
"X-Goog-Api-Key": "API_KEY",
"X-Goog-FieldMask": "routes.duration,routes.distanceMeters,routes.polyline.encodedPolyline"};
I've replaced your response section for you.
var response = await http.post(Uri.parse(url),
body: convert.jsonEncode({
"origin": {
"location": {
"latLng": {
"latitude": -6.2425120808113315,
"longitude": 106.85152720596324
}
},
},
"destination": {
"location": {
"latLng": {
"latitude": -6.2425120808113315,
"longitude": 106.85152720596324
}
},
},
"intermediates": {
"location": {
"latLng": {
"latitude": -6.178359098658539,
"longitude": 106.79219133887105
}
},
},
"travelMode": "DRIVE",
"routingPreference": "TRAFFIC_AWARE",
"polylineQuality": "HIGH_QUALITY",
"polylineEncoding": "ENCODED_POLYLINE",
//"departureTime": "",
"computeAlternativeRoutes": "FALSE",
"routeModifiers": {
"avoidTolls": false,
"avoidHighways": false,
"avoidFerries": false
},
"languageCode": "en-US",
"units": "IMPERIAL"
}),
headers: {
"Content-Type": "application/json",
"X-Goog-Api-Key": "API_KEY",
"X-Goog-FieldMask": "routes.duration,routes.distanceMeters,routes.polyline.encodedPolyline"
});

Related

How to pass a list of json to body of http Post request in Flutter?

I have objects that will filled by a user in a form. I parse these objects to json and add that json in a list to pass in body of request. But i cant do this.
submitQuestions() async {
var headers = {
'Content-Type': 'application/json',
'x-auth-token': '123edrfe33ewed'
};
var request = http.Request('POST', Uri.parse('url'));
request.body = json.encode({
"school_id": "123",
"teacher_id": "123",
"observer_id": "123",
"subject_id": "123",
"subject_name": "abc",
"class_id": "123",
"batch_id": "123",
"topic": "topic",
"academic_year": "2019-2020",
"remarks_data": [
{
"_id": "123",
"heading": "heading",
"Indicators": [
{
"name": "abc",
"_id": "123",
"remark": "abc",
"point": 4
},
{
"name": "abc",
"_id": "123",
"remark": "abc",
"point": 1
}
]
},
{
"_id": "123",
"heading": "abc",
"Indicators": [
{
"name": "abc",
"_id": "123",
"remark": "abc",
"point": 3
}
]
}
]
});
request.headers.addAll(headers);
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
print(await response.stream.bytesToString());
}
else {
print(response.reasonPhrase);
}
}
This json will change dynamically when the number of questions increase. I cannot place this json file in the body like this. How to Do this one.
Wrap each list of json with jsonEncode
like:
"remarks_data": jsonEncode(..)
and do not forget to import.
import 'dart:convert';
The request body try to use Map data type. You can create a model class to deal with it.
Example
class School {
String school_id;
String teacher_id;
String observer_id;
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['school_id'] = this.school_id;
data['teacher_id'] = this.teacher_id;
data['observer_id'] = this.observer_id;
...
return data;
}
}
/// Make sure your _school got data
School _school;
request.body = _school.toJson();

How do you parse JSON that is inside an array

I am new to flutter development and is experimenting with how to use the flutter HTTP package 0.12.0+2.
If the response looks like this...
{
"coord": {
"lon": -76.8403,
"lat": 38.9649
},
"weather": [
{
"id": 800,
"main": "Clear",
"description": "clear sky",
"icon": "01d"
}
],
"base": "stations",
"main": {
"temp": 93.47,
"feels_like": 99.34,
"temp_min": 88.84,
"temp_max": 97.74,
"pressure": 1017,
"humidity": 46
},
"visibility": 10000,
"wind": {
"speed": 1.99,
"deg": 304,
"gust": 1.99
},
"clouds": {
"all": 1
},
"dt": 1626462013,
"sys": {
"type": 2,
"id": 2030617,
"country": "US",
"sunrise": 1626429293,
"sunset": 1626481895
},
"timezone": -14400,
"id": 4369076,
"name": "Seabrook",
"cod": 200
}
Here is the code I have. Instead of printing all the data, how do I print only temp inside main
void getData() async {
Response response = await get('https://api.openweathermap.org/data/2.5/onecall?lat=38.964882&lon=-76.840271&exclude={part}&appid=b29e187fed23cf37dc160e6c115a270d');
// print(response.body);
Map data = jsonDecode(response.body);
print(data);
}
You can use:
void getData() async {
Response response = await get('https://api.openweathermap.org/data/2.5/onecall?lat=38.964882&lon=-76.840271&exclude={part}&appid=b29e187fed23cf37dc160e6c115a270d');
// print(response.body);
Map data = jsonDecode(response.body);
print(data['main']); //Will return [temp], [feels_like], [temp_min], etc..
print(data['main']['temp']); //Will return [93.47]
}
You can access the values of each fields by using the operator [$field] on the decoded json. Something like this:
void getData() async {
Response response = await get('https://api.openweathermap.org/data/2.5/onecall?lat=38.964882&lon=-76.840271&exclude=.{part}&appid=b29e187fed23cf37dc160e6c115a270d');
// print(response.body);
Map data = jsonDecode(response.body);
print(data['main']); // prints out { temp: 93.47, ...., humidity: 46 }
// what you want..
final mainTemp = data['main']['temp'];
print(mainTemp); // prints out 93.47.
print(data);
}
So, that's how you access the fields of of the decoded json-string response.
If you plan to use these received values throughout your app, consider changing the received response into an Interface which will provide you with more flexibility and also makes your code look cleaner.
Create Model Class here you can convert json to dart
https://javiercbk.github.io/json_to_dart/
Future<YourmodelName>getData() async {
YourmodelName data
Response response = await get('https://api.openweathermap.org/data/2.5/onecall?
lat=38.964882&lon=-76.840271&exclude=
{part}&appid=b29e187fed23cf37dc160e6c115a270d');
if (response.statusCode == 200) {
data = YourmodelName.fromJson(response.data);;
print(data.main.temp);}
return data;
}

How to send large json data inside the body of http post

I need to send a large object with my post method. but it kept giving me error.
Future getResults() async {
var res = await http.post('$SERVER_IP/api/anything/search',
headers: {'Authorization': token, "Accept": "application/json"},
body: {
"name": "",
"type": "",
"organization": "",
"state": "CA",
"appliesTo": {
"Camp": "true",
"Fees": "false",
"Lessons": "false",
},
}).catchError((e) => print({"error": e}));
return json.decode(res.body);
}
I realized that body only accept Map<String, String>. So I added json.encode to my "appliesTo" object.
Future getResults() async {
var res = await http.post('$SERVER_IP/api/anything/search',
headers: {'Authorization': token, "Accept": "application/json"},
body: {
"name": "",
"type": "",
"organization": "",
"state": "CA",
"appliesTo": json.encode({
"Camp": "true",
"Fees": "false",
"Lessons": "false",
}),
}).catchError((e) => print({"error": e}));
return json.decode(res.body);
}
After that it worked and I got a returned data. But my server was ignoring whole "appliesTo" object. So I didn't get the expected data. it's not a problem in my server. I tested it with postman. this flutter http post is not sending proper json body.
So my question is how to attatch large object to the body? was using json.encode at the middle of the object wrong? what is the proper way of doing it? can anyone help?
PS: I wraped the whole Map with json.encode and it gave me error
The documentation of the http package states that
If body is a Map, it's encoded as form fields using encoding. The content-type of the request will be set to "application/x-www-form-urlencoded"; this cannot be overridden.
If you want to send JSON data instead, you have to encode the body manually. Since the content type defaults to text/plain if body is a String, you also have to set the Content-Type header explicitly.
http.post('$SERVER_IP/api/anything/search',
headers: {
'Authorization': token,
"Accept": "application/json",
"Content-Type": "application/json"
},
body: json.encode({
"name": "",
"type": "",
"organization": "",
"state": "CA",
"appliesTo": {
"Camp": "true",
"Fees": "false",
"Lessons": "false",
},
}))

error on sending parameter values on event call

I have an intent which I am trying to invoke using event name, and trying to send parameters with it.
query_input = {
'event': {
"name": "greet",
"parameters": {
"mobile": "9876543210",
"plan": "pizza plan",
},
"language_code": "en"
}
}
response = session_client.detect_intent(session, query_input)
But I am getting error
ValueError: Protocol message Struct has no "mobile" field.
What am i doing wrong?
For now, I am sending parameters as below, its working fine:
from google.protobuf import struct_pb2
parameters = struct_pb2.Struct()
parameters["mobile"] = "9876543210"
parameters["plan"] = "pizza plan"
query_input = {
'event': {
"name": "greet",
"parameters": parameters,
"language_code": "en"
}
}
response = session_client.detect_intent(session, query_input)

Add event to calendar on SharePoint through REST API

I'm trying to add a calendar event to a SharePoint Calendar through REST API but i can't seems to find the relevant resources to achieve this.
If i understand correctly, the calendar in SharePoint is a List of events object, as such I should be able to add the event via ListItem object?
Sorry if this sounds wrong as I'm not familiar with SharePoint structure.
Thanks
This is the example for OAuth token Authentication but REST part is anyway like this.
var dataObj = {
"Subject": "Birthday Party"
"Body": {
"ContentType": "Text",
"Content": "Birthday Party for Cathy",
},
"Start": {
"dateTime": "2016-07-03T09:00:00Z",
"timeZone": "Asia/Tokyo"
},
"End": {
"dateTime": "2016-07-04T11:00:00Z",
"timeZone": "Asia/Tokyo"
},
"Location": {
"DisplayName": "Conference Room 1"
},
"ShowAs": "Busy",
"Attendees": [
{
"EmailAddress": { "Name": "Alex Darrow", "Address": "darrow.alex#company.com" },
"Type": "Required"
}
]
};
var url = "https://graph.microsoft.com/v1.0/me/events/";
var data = JSON.stringify(dataObj);
$.ajax({
url: url,
type: "POST",
data: data,
beforeSend: function (XMLHttpRequest) {
XMLHttpRequest.setRequestHeader("Accept", "application/json;odata.metadata=full;odata.streaming=true");
XMLHttpRequest.setRequestHeader('Authorization', 'Bearer ' + accessToken);
XMLHttpRequest.setRequestHeader("content-type", "application/json;odata=verbose");
},
success: function (result, textStatus, jqXHR) {
//Success
},
error: function (data) {
//
}});