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

DartFlutter

Dart Problem Overview


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"));

Dart Solutions


Solution 1 - Dart

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.

Solution 2 - Dart

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.

Solution 3 - Dart

I came here just trying to make an HTTP POST request. Here is an example of how to do that:

import 'dart:convert';
import 'package:http/http.dart';


makePostRequest() async {

  final uri = Uri.parse('http://httpbin.org/post');
  final headers = {'Content-Type': 'application/json'};
  Map<String, dynamic> body = {'id': 21, 'name': 'bob'};
  String jsonBody = json.encode(body);
  final encoding = Encoding.getByName('utf-8');

  Response response = await post(
    uri,
    headers: headers,
    body: jsonBody,
    encoding: encoding,
  );

  int statusCode = response.statusCode;
  String responseBody = response.body;
}

See also

Solution 4 - Dart

you need to use json.encode

example;

var match = {
  "homeTeam": {"team": "Team A"},
  "awayTeam": {"team": "Team B"}
};
var response = await post(Uri.parse(url),
    headers: {
      "Accept": "application/json",
      "Content-Type": "application/x-www-form-urlencoded"
    },
    body: json.encode(match),
    encoding: Encoding.getByName("utf-8"));

Solution 5 - Dart

I suggest using the Dio library. It supports a lot with working with APIs.

With newest Dio version. Simply do the following:

BaseOptions options = new BaseOptions(
baseUrl: "https://www.xx.com/api",
connectTimeout: 5000,
receiveTimeout: 3000,);
Dio dio = new Dio(options);
//
Map<String, String> params = Map();
params['username'] = '6388';
params['password'] = '123456';
//
response = await dio.post("/login", data: FormData.fromMap(params));

Solution 6 - Dart

On the place of "UserModel" write the name of your model and do not pass String in the body it will create a problem using "Map" as given below.

static Future<UserModel> performUserLogin(String username, String password) async{
    
        try{
    
          Map<String, String> headers = {"Content-type": "application/json"};
          
    
          Map<String, String> JsonBody = {
            'username':  username,
            'password': password
          };
    
          print("The JSON Object is here $body");
          // make POST request
          final response = await http.post(loginAPIURL,body: JsonBody);
          // check the status code for the result
          int statusCode = response.statusCode;
          print("Login calling $response");
    
    
          if (statusCode == 200){
    
          
    
          }else{
            return null;
            //return UserModel();
            throw Exception("Error in login");
          }
    
        } catch (e) {
          throw Exception(e);
        }
      }

Solution 7 - Dart

If you are using dio you can do it using :

dio.post(
      '/info',
      data: {'id': 5},
      options: Options(contentType: Headers.formUrlEncodedContentType),
    );

check https://github.com/flutterchina/dio for more details

Solution 8 - Dart

I did it like this with dart's http package. It's not too fancy. My endpoint wasn't accepting the parameters with other methods, but it accepted them like this, with the brackets included in the parameter.

import 'package:http/http.dart' as http;

String url = "<URL>";

Map<String, String> match = {
  "homeTeam[team]": "Team A",
  "awayTeam[team]": "Team B",
};

Map<String, String> headers = {
	"Content-Type": "application/x-www-form-urlencoded"
}

http.post(url, body: body, headers: headers).then((response){
	print(response.toString());
});

Solution 9 - Dart

Map<String, String> body = {
  'getDetails': 'true'
};

final response = await 
http.post("https://example.com/", body: body);

if (response.statusCode == 200) {
//Your code
}

Solution 10 - Dart

> Post encoded URL request

 static Future<http.Response> genearalRequest() async {
  Map<String,String> headers = new Map();
  headers["Content-Type"] = "application/x-www-form-urlencoded; charset=UTF-8";
 var data = {
    "data1": "datat1 value",
    "data2": "value2"
   };
var parts = [];
data.forEach((key, value) {
  parts.add('${Uri.encodeQueryComponent(key)}='
      '${Uri.encodeQueryComponent(value)}');
});
var formData = parts.join('&');

print(formData);
return await http.post('$baseUrl/oauth/token', headers: headers, body: formData);

}

Reference

Solution 11 - Dart

Simple get request using DIO :

    Future<dynamic> get(String uri, {
    Map<String, dynamic> queryParameters,
    Options options,
  }) async {
    try {
      var response = await _dio.get(
        uri,
        queryParameters: queryParameters,
        options: options,
      );
      return response.data;
    } on SocketException catch (e) {
      throw SocketException(e.toString());
    } on FormatException catch (_) {
      throw FormatException("Unable to process the data");
    } catch (e) {
      throw e;
    }
  }

Simple Post Request using DIO {you can send files and images as well} :

Future<dynamic> post(
    String uri, {
    data,
    Map<String, dynamic> queryParameters,
    Options options,
  }) async {
    try {
      var response = await _dio.post(
        uri,
        data: data,
        queryParameters: queryParameters,
        options: options,
      );
      return response.data;
    } on FormatException catch (_) {
      throw FormatException("Unable to process the data");
    } catch (e) {
      throw e;
    }
  }

Solution 12 - Dart

You can use addAll()...

var multipart = await http.MultipartFile.fromPath("userfile", file.path);//userFile must match server

var requestMultipart = http.MultipartRequest("POST", Uri.parse("uri"));

requestMultipart.files.add(multipart);

Map<String, String> data = {
  "name_of_image": "testName",
  "id_image": "2",//if the
  "upload_type": "Insert",
  "id_location": "2"
};

requestMultipart.fields.addAll(data);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionChinmay NaphadeView Question on Stackoverflow
Solution 1 - DartRichard HeapView Answer on Stackoverflow
Solution 2 - DartwenduView Answer on Stackoverflow
Solution 3 - DartSuragchView Answer on Stackoverflow
Solution 4 - DartNebi SarıgülView Answer on Stackoverflow
Solution 5 - DartDoan BuiView Answer on Stackoverflow
Solution 6 - DartTalha RasoolView Answer on Stackoverflow
Solution 7 - DartAsmaa AmrawyView Answer on Stackoverflow
Solution 8 - Dartk dimitrovView Answer on Stackoverflow
Solution 9 - DartTechalgowareView Answer on Stackoverflow
Solution 10 - Dartsujith sView Answer on Stackoverflow
Solution 11 - DartJawad AbbasiView Answer on Stackoverflow
Solution 12 - DartbuckleyJohnsonView Answer on Stackoverflow