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
CodePudding user response:
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
CodePudding user response:
Assuming that you're using package:http
, from the documentation for http.post
:
body
sets the body of the request. It can be aString
, aList<int>
or aMap<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