I am using TypeAheadFormField to show suggestions to the user as they type, with data pulled from an API designed to autosuggest items.
I have isolated the issue and it is failing at the suggestionsCallback:
stage, as the call is made. I have isolated it to the API call and the parsing of the data. I have tried lots of variations in the Class, call etc but can't get the error to go on running.
The error showing under text field(on simulator)
My Class (leaned down Quicktype.io) I have tried lots of versions and none worked for me. I am just trying to get the address
value from the List Items
to get it working
class Items {
Items({
required this.items,
});
List<Item>? items;
factory Items.fromJson(Map<String, dynamic> json) => Items(
items: json["items"] == null ? null : List<Item>.from(json["items"].map((x) => Item.fromJson(x))),
);
}
class Item {
final String address;
const Item({
required this.address,
});
static Item fromJson(Map<String, dynamic> json) => Item(
address: json['address'],
);
}
API returns in a Json List called Items
(Have removed bulk of data for this example, just 'address' I want at the moment)
{"items":[{"title":"Buckingham Palace","address":{"label":"Buckingham Palace Road, London, SW1E 5, United Kingdom"}"title":"Buckingham Place, London, SW1E 6, United Kingdom","resultType":"street","address":{"label":"Buckingham Place, London, SW1E 6, United Kingdom"}...
My API call for the data
class UserApi {
static FutureOr<Iterable<Items>> getUserSuggestions(String query) async {
final url = Uri.parse('https_call');
final response = await http.get(url);
if (response.statusCode == 200) {
final users = json.decode(response.body);
*Fails Here* return users.map((json) => Items.fromJson(json)).where((user) {
final nameLower = user.address.toLowerCase();
final queryLower = query.toLowerCase();
return nameLower.contains(queryLower);
}).toList();
} else {
throw Exception();
}
}
}
Thank you
CodePudding user response:
I think that the json you provide us is incorrect.
I tried to fix it, so I made it like below:
{
"items": [
{
"title": "Buckingham Palace",
"address": {
"label": "Buckingham Palace Road, London, SW1E 5, United Kingdom"
},"title": "Buckingham Place, London, SW1E 6, United Kingdom",
"resultType": "street",
"address": {
"label": "Buckingham Place, London, SW1E 6, United Kingdom"
}
}
]
}
And you can use the class below to parse it:
// To parse this JSON data, do
//
// final items = itemsFromJson(jsonString);
import 'dart:convert';
Items itemsFromJson(String str) => Items.fromJson(json.decode(str));
String itemsToJson(Items data) => json.encode(data.toJson());
class Items {
Items({
this.items,
});
final List<Item> items;
factory Items.fromJson(Map<String, dynamic> json) => Items(
items: json["items"] == null ? null : List<Item>.from(json["items"].map((x) => Item.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"items": items == null ? null : List<dynamic>.from(items.map((x) => x.toJson())),
};
}
class Item {
Item({
this.title,
this.address,
this.resultType,
});
final String title;
final Address address;
final String resultType;
factory Item.fromJson(Map<String, dynamic> json) => Item(
title: json["title"] == null ? null : json["title"],
address: json["address"] == null ? null : Address.fromJson(json["address"]),
resultType: json["resultType"] == null ? null : json["resultType"],
);
Map<String, dynamic> toJson() => {
"title": title == null ? null : title,
"address": address == null ? null : address.toJson(),
"resultType": resultType == null ? null : resultType,
};
}
class Address {
Address({
this.label,
});
final String label;
factory Address.fromJson(Map<String, dynamic> json) => Address(
label: json["label"] == null ? null : json["label"],
);
Map<String, dynamic> toJson() => {
"label": label == null ? null : label,
};
}
CodePudding user response:
Solution was to put
if (response.statusCode == 200) {
Map<String, dynamic> users1 = json.decode(response.body);
List<dynamic> users = users1["items"];
in place of
if (response.statusCode == 200) {
final List users = json.decode(response.body);