2

Context: I want to register new customer to my API server(with package:http/http.dart).

Problem: This error was thrown:

flutter: type 'List<Map<String, String?>>' is not a subtype of type 'String' in type cast

I think flutter is complaining about the type of metadata property, but I have no clue on how to resolve it.

I tried to create a Map<dynamic, dynamic> object but it does not help as well.

var response = await _httpClient.post(
        createCustomerUrl,
        body: {
          'email': customerModel.email,
          'first_name': customerModel.firstName,
          'last_name': customerModel.lastName,
          'password': customerModel.password,
          'username': customerModel.username,
          'meta_data': [
            {'key': 'birthdate', 'value': customerModel.birthdate},
          ],
        },
      );

2 Answers 2

3

@Abbasihsn answer was almost there. JSON.encode + 'Content-Type': 'application/json' in the headers solve the problem.

var response = await _httpClient.post(
        createCustomerUrl,
        body: json.encode({
          'email': customerModel.email,
          'first_name': customerModel.firstName,
          'last_name': customerModel.lastName,
          'password': customerModel.password,
          'username': customerModel.username,
          'meta_data': [
            {'key': 'birthdate', 'value': customerModel.birthdate},
          ],
        }),
        headers: { 'Content-Type': 'application/json' }
      );

The error message is due to http package internally perform type check and trying to cast the body to Map<String, String>. Here is the code snippet extracted from the http package that causes the error:

  /// Sends a non-streaming [Request] and returns a non-streaming [Response].
  Future<Response> _sendUnstreamed(
      String method, Uri url, Map<String, String>? headers,
      [body, Encoding? encoding]) async {
    var request = Request(method, url);

    if (headers != null) request.headers.addAll(headers);
    if (encoding != null) request.encoding = encoding;
    if (body != null) {
      if (body is String) {
        request.body = body;
      } else if (body is List) {
        request.bodyBytes = body.cast<int>();
      } else if (body is Map) {
        request.bodyFields = body.cast<String, String>();  // <-- this line
      } else {
        throw ArgumentError('Invalid request body "$body".');
      }
    }

    return Response.fromStream(await send(request));
  }
Sign up to request clarification or add additional context in comments.

Comments

1

try encoding your body to a JSON, like this:

var response = await _httpClient.post(
        createCustomerUrl,
        body: json.encode({
          'email': customerModel.email,
          'first_name': customerModel.firstName,
          'last_name': customerModel.lastName,
          'password': customerModel.password,
          'username': customerModel.username,
          'meta_data': [
            {'key': 'birthdate', 'value': customerModel.birthdate},
          ],
        }),
      );

4 Comments

Sadly not working, json.encode return a stringified version of the request body, but the server is expecting the request body to be key-value pair json, when passing the string to server, server complain missing params.
ok, have you tried json.encode only for meta_data': [...], section?
I have solved, you are almost there, the solution is json.encode with explicitly add Content-Type: application/json to the headers. Thank you for helping.
your welcome. if my answer was helpful, I would be grateful if you vote it up or set it as an acceptable solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.