I am trying make an http post request with the method below. when I run the method I keep getting the message that an exeption has occured and am being pointed to this utils.dart file. From what am seeing my best guess is that there is a problem converting the map data I have provided in the url into the query string. Icant seem to find what am doing wrong tho.How may I solve this.
Request Method
Future<List>getdata()async{
print("Loading ....");
String theUrl ="https://http://127.0.0.1/codeishweb/notifiedUser.php";
var res = await http.post(Uri.encodeFull(theUrl),headers: {"Accept":"application/json"},body: {"notID":2},);
var responseBody = json.decode(res.body);
print("results ::$responseBody");
//print("the response at position something::::\nHeading\n${responseBody[0][7]['post_head']}\nBody\n${responseBody[0][7]['post_body']}");
return responseBody;
}
Error message in utils.dart
/// Converts a [Map] from parameter names to values to a URL query string.
///
/// mapToQuery({"foo": "bar", "baz": "bang"});
/// //=> "foo=bar&baz=bang"
String mapToQuery(Map<String, String> map, {Encoding encoding}) {
var pairs = <List<String>>[];
map.forEach((key, value) => pairs.add([
Uri.encodeQueryComponent(key, encoding: encoding),
Uri.encodeQueryComponent(value, encoding: encoding)
]));
return pairs.map((pair) => "${pair[0]}=${pair[1]}").join("&");
}
Related
Trying to apply abs_path from RFC2616 (https://www.rfc-editor.org/rfc/rfc2616#section-5.1.2) but receiving callout exception 'System.CalloutException: no protocol: /animals'.
End point url trying in following example : http://th-apex-http-callout.herokuapp.com/animals
eg.
Http http = new Http();
HttpRequest request = new HttpRequest();
request.setHeader('Host','th-apex-http-callout.herokuapp.com');
request.setEndpoint('/animals');
request.setMethod('GET');
HttpResponse response = http.send(request);
// If the request is successful, parse the JSON response.
if (response.getStatusCode() == 200) {
// Deserializes the JSON string into collections of primitive data types.
Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
// Cast the values in the 'animals' key as a list
List<Object> animals = (List<Object>) results.get('animals');
System.debug('Received the following animals:');
for (Object animal: animals) {
System.debug(animal);
}
}
expected output :
Received the following animals:
majestic badger
fluffy bunny
etc...
I've never tried sending Host as a header but this works just fine
request.setEndpoint('http://th-apex-http-callout.herokuapp.com/animals');
I do simple upload image to server using http packages. But the problem is , when i upload it i got error Unhandled Exception: InternalError: 'Filter error, bad data'.
Upload
Future testUpload(File selfieImage, String pembertang) async {
final result = await reusableRequestServer.requestServer(() async {
//create multipart request for POST or PATCH method
var request = http.MultipartRequest('POST', Uri.parse('$baseApiUtang/addUtang'));
//add text fields
request.fields['pembertang'] = '$pembertang';
//create multipart using filepath, string or bytes
var pic = await http.MultipartFile.fromPath('selfie', selfieImage.path);
//add multipart to request
request.files.add(pic);
var response = await request.send();
//Get the response from the server
var responseData = await response.stream.toBytes();
var responseString = String.fromCharCodes(responseData);
print('responseData : $responseData');
print('responseString : $responseString');
return responseString;
});
return result;
}
With this strange problem , i try it with postman but it's work like i want.
My opinion, it's not problem in my backend code. I missed something ?
Update
Similiar problem with me on this issue
Update 2
When i look inside the code and print variable 1 by 1, i got status code 403
Hi can you pls try following code
var stream = new http.ByteStream(Stream.castFrom(imageFile.openRead()));
// get file length
var length = await imageFile.length();
// create multipart request
var request = new http.MultipartRequest("POST", uri);
var name = firstname +"."+imageFile.path.split(".").last;
// multipart that takes file
var multipartFile = new http.MultipartFile('profile', stream, length,
filename: basename(name));
In my case my can not take so much long name so i customise image name and then tried and its working .
so you can also try this.
I want to send parameters with an http GET request in dart. The first answer here demonstrates it well: How do you add query parameters to a Dart http request?
var uri =
Uri.https('www.myurl.com', '/api/query', queryParameters);
However, a major problem is that queryParameters only accepts:
Map<String, String>
This doesn't allow me to pass in lists/arrays.
If i change my get request to a post request, I am easily able to send a
body (as a json encoded String) as outlined by the flutter docs: https://pub.dev/documentation/http/latest/http/post.html
post(url, {Map<String, String> headers, body, Encoding encoding})
However, the get request has no such equivalent argument for query parameters: https://pub.dev/documentation/http/latest/http/get.html
get(url, {Map<String, String> headers})
I have also tried adding query parameters directly to the url like so:
get('www.myurl.com/api/query/?array[]=value1&array[]=value2&array[]=value3)
but the square brackets [] always get transformed into %5B%5D when I receive it in the server.
Any help is appreciated.
Thanks
In fact, queryParameter takes Map<String, dynamic>. Check the source code:
factory Uri(
{String scheme,
String userInfo,
String host,
int port,
String path,
Iterable<String> pathSegments,
String query,
Map<String, dynamic /*String|Iterable<String>*/ > queryParameters,
String fragment}) = _Uri;
The dynamic can be either a String or an Iterable<String>. So,
var uri = Uri(
scheme: 'http',
host: 'www.myurl.com',
path: '/api/query/',
queryParameters: {
'array': ['value1', 'value2', 'value3'],
},
);
print(uri);
prints:
http://www.myurl.com/api/query/?array=value1&array=value2&array=value3
Simple is, that I am trying to make a PUT request to my API but I get the type error of:
_CastError (type 'List<String>' is not a subtype of type 'String' in type cast)
My API accepts an Array of strings (string[]), which I know work because I am currently consuming it on the sibling web platform. So I am trying to replicate that on the Flutter app with the below code. At the moment it is just static code.
I know, that the http module is only accept string but is there a way to get around this? As it does not make sense, as what happens if we want to post an int, bool or <List<String>>. I know you can obviously convert using .toString() but my API has certain validation and is rigid on what it can accept.
Code below:
When I use this payload it works because it follows the rigid types of the Http module (<String, String>)
Map<String, String> payloadThatWorks = {"first_name": "First Name"};
Now when I want to give the payload of the type Map<String, List<String>> with the code below:
Map<String, List<String>> payload = {
"personal_settings": ["allow-notification-discussion-mentions"]
};
It throws the error of _CastError (type 'List<String>' is not a subtype of type 'String' in type cast)
in the http.put function below:
Main API Helper function
static Future<http.Response> queryPut(String apiPath, {dynamic body}) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String accessToken = prefs.getString('access_token');
var response = await http.put(
Uri.encodeFull(_urlBase + '$apiPath'),
body: body,
headers: {
HttpHeaders.authorizationHeader: "Bearer $accessToken",
'Accept': 'application/json'
},
);
return response;
}
However, when helper function is called in my Widget...
http.Response response =
await ApiService.queryPut('/api/users/$username', body: payload);
So i'm in a spot where the http module does not accept anything put <String> but the API does not accept anything but an Array or <List<String>>
How can I get round this or understand why the http put method is so rigid?
Thank you in advance :)
Sam
You can import dart:convert and use its jsonEncode to convert your map or array of map into a string
So basically you will have to do the following
String payloadStr = jsonEncode(payload)
and use this payloadStr to pass in the http methods. Similarly you can use JsonDecoder to convert json string to Map or Array of map.
Goal: retrieve the single value "test" in Angular.
Problem: I get an error message
Error: SyntaxError: Unexpected token e in JSON at position 1 at JSON.parse ()
What syntax am I missing?
ASP.NET
// https://localhost:44353/api/Jobadvertisement/VVValidate/4
[HttpGet("VVValidate/{id:int}")]
public ActionResult<String> VVValidate(int id)
{
return "test";
}
Angular
const url = environment.url
let asdfasdf2 = url + 'api/Jobadvertisement/VVValidate/' + "4";
var dsfsdssf = this.http.get(asdfasdf2).subscribe(data => {
console.log(data);
});
Can you please try using httpOptions in Angular with something like this:
const url = environment.url;
let asdfasdf2 = url + 'api/Jobadvertisement/VVValidate/' + "4";
var dsfsdssf = this.http.get(asdfasdf2, { responseType: 'text' }).subscribe(data => { console.log(data); });
You need to change ActionResult to string:
[HttpGet("VVValidate/{id:int}")]
public string VVValidate(int id)
{
return "test";
}
Angular's HttpClient expects JSON data per default, which is why you get a JSON deserialization error upon returning plain text from your API.
You need to pass responseType: 'text' as option to the get method, in order to prevent HttpClient from treating your data as JSON:
httpClient.get("url", { responseType: 'text' });
You can find more information regarding this in Angular's Documentation.
Even though your API code works as it is, I'd like to point out two things:
You can unwrap your String and remove the ActionResult, as it is not needed.
I would encourage you to use the string type instead of System.String. For a detailed explanation, please refer to this.
Your code would look like this after applying these changes:
[HttpGet("VVValidate/{id:int}")]
public string VVValidate(int id)
{
return "test";
}