Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make HTTP POST request with url encoded body in flutter?

Tags:

flutter

dart

I'm trying to make an post request in flutter with content type as url encoded. When I write body : json.encode(data), it encodes to plain text.

If I write body: data I get the error type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'String' in type cast

This is the data object

var match = {   "homeTeam": {"team": "Team A"},   "awayTeam": {"team": "Team B"} }; 

And my request

var response = await post(Uri.parse(url),     headers: {       "Accept": "application/json",       "Content-Type": "application/x-www-form-urlencoded"     },     body: match,     encoding: Encoding.getByName("utf-8")); 
like image 985
Chinmay Naphade Avatar asked Apr 12 '18 13:04

Chinmay Naphade


People also ask

How do I use HTTP URL in flutter?

Add the http packageTo install the http package, add it to the dependencies section of the pubspec.yaml file. You can find the latest version of the http package the pub.dev. Import the http package.

How do I send Urlencoded data in flutter?

Response response = await http. post( url, body: "name=$name&surname=$firstName&mail=$mail&password=$password&birth=$birthDate&phone=$phone&confirmPassword=$confirmPassword", headers: { "Content-Type": "application/x-www-form-urlencoded" }, encoding: convert. Encoding. getByName("utf-8"), );


2 Answers

You need to add three additional steps: First, you need to convert the JSON map to a String (using json.encode) Then you need to Uri encode it if you want to send it as application/x-www-form-urlencoded. Lastly, you need to give the parameter that you are posting a name.

For example (note, this is using the dart:io HttpClient, but it's basically the same):

  Future<HttpClientResponse> foo() async {     Map<String, dynamic> jsonMap = {       'homeTeam': {'team': 'Team A'},       'awayTeam': {'team': 'Team B'},     };     String jsonString = json.encode(jsonMap); // encode map to json     String paramName = 'param'; // give the post param a name     String formBody = paramName + '=' + Uri.encodeQueryComponent(jsonString);     List<int> bodyBytes = utf8.encode(formBody); // utf8 encode     HttpClientRequest request =         await _httpClient.post(_host, _port, '/a/b/c');     // it's polite to send the body length to the server     request.headers.set('Content-Length', bodyBytes.length.toString());     // todo add other headers here     request.add(bodyBytes);     return await request.close();   } 

The above is for the dart:io version (which, of course, you can use in Flutter) If you would like to stick with the package:http version, then you need to tweak your Map a bit. body must be a Map<String, String>. You need to decide what you want as your POST parameters. Do you want two: homeTeam and awayTeam? or one, say, teamJson?

This code

  Map<String, String> body = {     'name': 'doodle',     'color': 'blue',     'homeTeam': json.encode(       {'team': 'Team A'},     ),     'awayTeam': json.encode(       {'team': 'Team B'},     ),   };    Response r = await post(     url,     body: body,   ); 

produces this on the wire

name=doodle&color=blue&homeTeam=%7B%22team%22%3A%22Team+A%22%7D&awayTeam=%7B%22team%22%3A%22Team+B%22%7D

alternatively, this

  Map<String, String> body = {     'name': 'doodle',     'color': 'blue',     'teamJson': json.encode({       'homeTeam': {'team': 'Team A'},       'awayTeam': {'team': 'Team B'},     }),   };    Response r = await post(     url,     body: body,   ); 

produces this on the wire

name=doodle&color=blue&teamJson=%7B%22homeTeam%22%3A%7B%22team%22%3A%22Team+A%22%7D%2C%22awayTeam%22%3A%7B%22team%22%3A%22Team+B%22%7D%7D

the package:http client takes care of: encoding the Uri.encodeQueryComponent, utf8 encoding (note that that's the default, so no need to specify it) and sending the length in the Content-Length header. You must still do the json encoding.

like image 185
Richard Heap Avatar answered Sep 20 '22 16:09

Richard Heap


I'd like to recommend dio package to you , dio is a powerful Http client for Dart/Flutter, which supports Interceptors, FormData, Request Cancellation, File Downloading, Timeout etc.

dio is very easy to use, in your case you can:

Map<String, String> body = { 'name': 'doodle', 'color': 'blue', 'teamJson': {   'homeTeam': {'team': 'Team A'},   'awayTeam': {'team': 'Team B'},   }, };  dio.post("/info",data:body, options:    new Options(contentType:ContentType.parse("application/x-www-form-urlencoded")))     

dio can encode the data automatically.

More details please refer to dio.

like image 41
wendu Avatar answered Sep 20 '22 16:09

wendu