0

In this instance, i have details of an item entered by user and need to add them to backend server. Here is my method:

Future<AddItemResponseModel> AddItem(
  String name,
  String description,
  String picture, // image encoded to base64 String
  List<String> tags,
  bool liked,
  String token,
) async {
  final String url = "API_URL";
  final response = await http.post(Uri.parse(url), body: {
    "name": name,
    "description": description,
    "picture": picture,
    "date": "date",
    "tags": tags,
    "like": liked,
    "location": "something"
  }, headers: {
    "authtype": "custom",
    "x-access-token": token
  });
  if (response.statusCode == 200) {
    final String responseString = response.body;
    print(responseString);
    return AddItemResponseModelFromJson(responseString);
  } else {
    // Error message to user
  }
}

And here is the onTap function of a GestureDetector widget that calls this method.

onTap: () async {
                                    if (checkCondition) {
                                      final AddItemResponseModel item =
                                          await AddItem(
                                        itemName, // name
                                        itemDescription, // description 
                                        _image64, // image encoded to base64 String
                                        tagNames, // List<String>
                                        true,  // liked
                                        token, // x-access-token
                                      );
                                      setState(() {
                                        _item = item;  // _item is of datatype <AddItemResponseModel> created to be accessed across this page
                                      });
                                      if (_item.success == true) {
                                        Navigator.push(
                                          context,
                                          MaterialPageRoute(
                                              builder: (context) =>
                                                  ItemAdded()),
                                        );
                                      }
                                    }
                                    setState(() {
                                      if (screen_no < 3) screen_no += 1;
                                    });
                                  }

I get the following error, but haven't been able to diagnose the cause.

Unhandled Exception: type 'List<String>' is not a subtype of type 'String' in type cast
#0      CastMap.forEach.<anonymous closure> (dart:_internal/cast.dart:288:25)
#1      _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:539:8)
#2      CastMap.forEach (dart:_internal/cast.dart:287:13)
#3      mapToQuery (package:http/src/utils.dart:17:7)
#4      Request.bodyFields= (package:http/src/request.dart:137:12)
#5      BaseClient._sendUnstreamed (package:http/src/base_client.dart:87:17)
#6      BaseClient.post (package:http/src/base_client.dart:32:7)
#7      post.<anonymous closure> (package:http/http.dart:69:16)
#8      _withClient (package:http/http.dart:164:20)
#9      post (package:http/http.dart:68:5)
#10     AddItem (package:krunch_app/Pages/AddItem/itemAddPage.dart:37:31)
#11     _ItemAddPageState.build.<anonymous closure> (package:krunch_app/Pages/AddItem/itemAddPage.dart:492:49)
#12     _ItemAddPageState.build.<anonymous closure> (package:krunc<…>

Thanks for all the help in advance.

EDIT-1:

This is my AddItemResponseModel

class AddItemResponseModel {
  AddItemResponseModel({this.success, this.error, this.id});

  bool? success;
  String? error;
  String? id;

  factory AddItemResponseModel.fromJson(Map<String, dynamic> json) =>
      AddItemResponseModel(
          success: json["success"], error: json["error"], id: json["id"]);
}

AddItem is just a function which returns a AddItemResponseModel datatype by decoding the json response

Calladrus2k1
  • 84
  • 11

2 Answers2

0

Your error is right in the Unhandled Exception. You are trying to cast your tags field as a List<String> type, when your API response gives you only a String. As is for now, try to change the type value like this:

String tags
0

Assuming that you're using package:http, from the documentation for http.post:

body sets the body of the request. It can be a String, a List<int> or a Map<String, String>.

You are passing a Map for body, so that Map is expected to have String keys and String values. You are attempting to include tags as a value to that Map, yet tags is a List<String>. (Similarly, liked will also produce an error since it is a bool and not a String.)

If you need to pass multiple items for a field, you must combine them and encode them to a single String first.

Also see: Dart Http POST with duplicate key form

jamesdlin
  • 81,374
  • 13
  • 159
  • 204
  • After converting both tags and liked to String, i get this `Unhandled Exception: FormatException: Unexpected character (at character 1)` – Calladrus2k1 Apr 05 '22 at 05:38
  • @Calladrus2k1 That sounds like a separate problem. I can't help you with that if you don't provide any details about where it's coming from. (I presume you're getting that exception when attempting to decode the response. What is the response? Possibly the response isn't what you expect because the server rejected your request.) – jamesdlin Apr 05 '22 at 05:39
  • I am getting no response, from postman it says "could not send request" – Calladrus2k1 Apr 05 '22 at 05:47
  • @Calladrus2k1 As I said, it sounds like a separate problem. It's quite possible (if not likely) that the server is rejecting your request because however you're encoding your `List` as a single `String` isn't what the server expects. Or maybe there's something else malformed in your request body. If so, it's going to be specific to your API/server. – jamesdlin Apr 05 '22 at 06:20
  • 1
    @Calladrus2k1 Another possibility is that you're doing nothing wrong when sending the request and that whatever request you're making is *supposed* to receive an empty string in response, but your `AddItemResponseModelFromJson` function does not handle that. – jamesdlin Apr 05 '22 at 06:24