httpflutterdartform-data

How make a http post using form data in flutter?


I'm trying to do a http post request and I need to specify the body as form-data, because the server don't take the request as raw.

This is what I'm doing:

import 'dart:convert';

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

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

  postTest() async {
    final uri = 'https://na57.salesforce.com/services/oauth2/token';
    var requestBody = {
      'grant_type':'password',
      'client_id':'3MVG9dZJodJWITSviqdj3EnW.LrZ81MbuGBqgIxxxdD6u7Mru2NOEs8bHFoFyNw_nVKPhlF2EzDbNYI0rphQL',
      'client_secret':'42E131F37E4E05313646E1ED1D3788D76192EBECA7486D15BDDB8408B9726B42',
      'username':'example@mail.com.us',
      'password':'ABC1234563Af88jesKxPLVirJRW8wXvj3D'
    };

    http.Response response = await http.post(
        uri,
        body: json.encode(requestBody),
    );

    print(response.body);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Container(
        child: Center(
          child: RaisedButton(
            child: Text('Press Here'),
            onPressed: (){
              postTest();
            },
          ),
        ),
      ),
    );
  }
}

This is the actual response:

{
    "error": "unsupported_grant_type",
    "error_description": "grant type not supported"
}

Actual response

This is the expected response:

{
    "access_token": "00D0b000000Bb08!AR8AQO.s8mAGXCbwV77FXNLQqc2vtl8g6_16miVbgWlQMsuNHsaf2IGLUwnMVXBOfAj19iznhqhwlPOi4tagvf7FFgiJJgoi",
    "instance_url": "https://na57.salesforce.com",
    "id": "https://login.salesforce.com/id/00D0b000000Bb08EAC/0050b000005nstiAAA",
    "token_type": "Bearer",
    "issued_at": "1567993324968",
    "signature": "1+Zd/dSh9i7Moh2U0nFJLdXkVHqPlPVU6emwdYzXDPk="
}

Expected response

You can test this on postman switching the body between raw (you get the actual response) and form-data (you get the expected response)

PS: The headers are temporary headers created by the client tool.


Solution

  • Use Map instead, because body in http package only has 3 types: String, List<int> or Map<String, String>.

    Try this:

    final Uri uri = Uri.parse('https://na57.salesforce.com/services/oauth2/token');
        final map = <String, dynamic>{};
        map['grant_type'] = 'password';
        map['client_id'] = '3MVG9dZJodJWITSviqdj3EnW.LrZ81MbuGBqgIxxxdD6u7Mru2NOEs8bHFoFyNw_nVKPhlF2EzDbNYI0rphQL';
        map['client_secret'] = '42E131F37E4E05313646E1ED1D3788D76192EBECA7486D15BDDB8408B9726B42';
        map['username'] = 'example@mail.com.us';
        map['password'] = 'ABC1234563Af88jesKxPLVirJRW8wXvj3D';
    
    http.Response response = await http.post(
        uri,
        body: map,
    );