31

How to perform HTTP POST using the console dart application (using dart:io or may be package:http library. I do something like that:

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

  http.post(
    url,
    headers: {HttpHeaders.CONTENT_TYPE: "application/json"},
    body: {"foo": "bar"})
      .then((response) {
        print("Response status: ${response.statusCode}");
        print("Response body: ${response.body}");
      }).catchError((err) {
        print(err);
      });

but get the following error:

Bad state: Cannot set the body fields of a Request with content-type "application/json".
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
Roman
  • 2,145
  • 4
  • 26
  • 33

2 Answers2

70

This is a complete example. You have to use json.encode(...) to convert the body of your request to JSON.

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


var url = "https://someurl/here";
var body = json.encode({"foo": "bar"});

Map<String,String> headers = {
  'Content-type' : 'application/json', 
  'Accept': 'application/json',
};

final response =
    http.post(url, body: body, headers: headers);
final responseJson = json.decode(response.body);
print(responseJson);

Generally it is advisable to use a Future for your requests so you can try something like

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

Future<http.Response> requestMethod() async {
    var url = "https://someurl/here";
    var body = json.encode({"foo": "bar"});

    Map<String,String> headers = {
      'Content-type' : 'application/json', 
      'Accept': 'application/json',
    };

    final response =
        await http.post(url, body: body, headers: headers);
    final responseJson = json.decode(response.body);
    print(responseJson);
    return response;
}

The only difference in syntax being the async and await keywords.

vishal dharankar
  • 7,536
  • 7
  • 57
  • 93
draysams
  • 1,199
  • 1
  • 11
  • 18
35

From http.dart:

/// [body] sets the body of the request. It can be a [String], a [List<int>] or
/// a [Map<String, String>]. If it's a String, it's encoded using [encoding] and
/// used as the body of the request. The content-type of the request will
/// default to "text/plain".

So generate the JSON body yourself (with JSON.encode from dart:convert).

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • It works but with the wrong content type... If the remote server uses content negociation, it will not recognize the request body as JSON (and will not parse it as an object). – CedX Jun 02 '17 at 12:27
  • 1
    @CédricBelin — The content type is not wrong. The code already in the question was setting it to the right value for a JSON body. – Quentin Jun 02 '17 at 12:28
  • @Quentin Absolutely, you're right : not enough concentrated when I read the documentation of the package "http" => `The content-type of the request will be set [...] this cannot be overridden` This sentence was associated with a `Map` body, not a `String` one. – CedX Jun 02 '17 at 12:32
  • If I do such a thing I am not able to retreive the request with $_POST in PHP side of the project. Do you have an idea why? – Martin. Feb 09 '19 at 22:40
  • @Martin. — PHP only supports url encoded and multipart form encoded requests for automatic decoding to $_POST (i.e. not JSON encoded requests). – Quentin Feb 10 '19 at 21:22