Alvin Quezon
Alvin Quezon

Reputation: 209

Flutter HTTP Post returns 415

I have an issue with using Method.Post on my flutter app using http dart library. It seems that when I tried to post data from my WebAPI it gaves me a StatusCode 415. See my code below:

Code Login:

Future<User> login(User user) async {
print(URLRequest.URL_LOGIN);
return await _netUtil.post(Uri.encodeFull(URLRequest.URL_LOGIN), body: {
  'username': user.username,
  'password': user.password
}, headers: {
  "Accept": "application/json",
}).then((dynamic res) {
  print(res.toString());
});
}

Code NetworkUtils:

Future<dynamic> post(String url, {Map headers, body, encoding}) async {
return await http
    .post(url, body: body, headers: headers, encoding: encoding)
    .then((http.Response response) {
  final String res = response.body;
  final int statusCode = response.statusCode;

  if (statusCode < 200 || statusCode > 400 || json == null) {
    throw new Exception('Error while fetching data.');
  }

  return _decoder.convert(res);
});
}

Does anyone knew whats going on my code?

Upvotes: 11

Views: 11827

Answers (3)

Antonin GAVREL
Antonin GAVREL

Reputation: 11269

If you are using Flutter with Rust backend you might have several things to do. It was working fine previously with NodeJS so I was slightly surprised and had to debug little by little.

1/ Encode using jsonEncode and not toJson()

 String body = jsonEncode(user); // give you a string instead of a Map. 

user is the Object for Class User, defined below, of course you can use any Object you like to send in the body of your request.

2/ Add the headers

    var headers = {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
    };

Now the request should be working:

    final response = await http.post(Uri.parse(url), headers: headers, body: body);

I also made it work following @Rooshan 's answer and using a String instead of a Map but it was not very pretty to say the least, still it did the job:

  String toJson() => """{
    "firstname": "$firstname",
    "lastname": "$lastname",
    "email": "$email",
    "password": "$password"
  }""";

In this case you can write directly:

String body = user.toJson();

For reference class user:

class User {
  String firstname;
  String lastname;
  String email;
  String? password;


User(this.firstname, this.lastname, this.email, {this.password = ""});

  Map<String, dynamic> toJson() => {
        "firstname": firstname,
        "lastname": lastname,
        "email": email,
        "password": password!,
      };
}

Upvotes: 1

Rooshan
Rooshan

Reputation: 19

@Alvin Quezon

I met the same error as yours and fix it, please see below.

[Error]

StateError (Bad state: Cannot set the body fields of a Request with content-type "application/json".)

[Reason]

when you use the Flutter plug 'http.dart' method 'http.post()', you should read the document in detail below (note the black fonts):

Sends an HTTP POST request with the given headers and body to the given URL.
[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".

If [body] is a List, it's used as a list of bytes for the body of the
request.

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.

[encoding] defaults to [utf8].

For more fine-grained control over the request, use [Request] or
[StreamedRequest] instead.
Future<Response> post(Uri url,
{Map<String, String>? headers, Object? body, Encoding? encoding}) =>
_withClient((client) =>
    client.post(url, headers: headers, body: body, encoding: encoding));

[Solution]

So just encode your body as a string ,then you can set the header 'content-type' as 'application/json'. see the codes of @diegoveloper answered!

Upvotes: 1

diegoveloper
diegoveloper

Reputation: 103561

Try adding this new header:

headers: {
  "Accept": "application/json",
  "content-type":"application/json"
}

UPDATE

Ok now you need to send json data, like this :

        import 'dart:convert';


         var body = jsonEncode( {
          'username': user.username,
          'password': user.password
        });


        return await _netUtil.post(Uri.encodeFull(URLRequest.URL_LOGIN), body: body, headers: {
          "Accept": "application/json",
          "content-type": "application/json"
        }).then((dynamic res) {
          print(res.toString());
        });
        }

Upvotes: 23

Related Questions