-
-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
selectedValueWidgetFn creates an error. #108
Comments
Hi @phranklins , Thanks for raising this issue. I tried again the code example in #103 which seems to be the closest I could get to your situation and I got no issue running with latest version of the plugin. Could it be that the error occurs because your data is different? If I had to guess, I would suspect that your items are indexed with integers and not strings. In data terms, they are a list while the example code expects a map. However, without the code, it is hard to confirm. Do you have some code you could share so that I can try to investigate further? |
I'm actually pretty much using your example code as is so it's weird that I'm running into issues while you aren't. The biggest differences between your code and mine are:
Here is basically the code I have for the widget:
|
Thanks for the additional details! I cannot run your example right now. Do you have a specific line/character pointed at with the "got a String while expecting an int" error? If you run in debug mode with a breakpoint on this line, does the data look as expected? |
Yeah the data looks as expected, but for some reason I feel the search choices code is what's blocking it. I wish the post had line numbers. Basically I've experienced two errors:
|
Your code turns the import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:search_choices/search_choices.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:http/http.dart';
class SearchCapitals extends StatefulWidget {
const SearchCapitals({
Key? key,
this.width,
this.height,
}) : super(key: key);
final double? width;
final double? height;
@override
_SearchCapitalsState createState() => _SearchCapitalsState();
}
class _SearchCapitalsState extends State<SearchCapitals> {
@override
String? selectedValueSingleDialogPagedFuture;
PointerThisPlease<int> currentPage = PointerThisPlease<int>(1);
Widget build(BuildContext context) {
return SearchChoices.single(
icon: const Icon(Icons.keyboard_arrow_down_rounded),
displayClearIcon: false,
padding: 4,
value: selectedValueSingleDialogPagedFuture,
hint: Text(
"Search capitals",
style: TextStyle(
color: black,
fontWeight: FontWeight.w300),
),
searchHint: Text(
"Search capitals",
style: TextStyle(fontWeight: FontWeight.bold),
),
underline: Container(
height: 0,
),
onChanged: (value) {
setState(() {
selectedValueSingleDialogPagedFuture = value;
});
},
isExpanded: true,
itemsPerPage: 15,
currentPage: currentPage,
selectedValueWidgetFn: (item) {
return DropdownMenuItem(child: (Text(item)));
},
displayItem: (item, selected) {
return (Row(children: [
selected
? Icon(
Icons.radio_button_checked,
color: Colors.grey,
)
: Icon(
Icons.radio_button_unchecked,
color: Colors.grey,
),
SizedBox(width: 7),
Expanded(
child: item,
),
]));
},
futureSearchFn: (String? keyword, String? orderBy, bool? orderAsc,
List<Tuple2<String, String>>? filters, int? pageNb) async {
String filtersString = "";
int i = 1;
filters?.forEach((element) {
filtersString += "&filter" +
i.toString() +
"=" +
element.item1 +
"," +
element.item2;
i++;
});
Response response = await get(Uri.parse(
"https://corsproxy.io/?https://searchchoices.jod.li/exampleList.php?page=${pageNb ?? 1},10${orderBy == null ? "" : "&order=" + orderBy + "," + (orderAsc ?? true ? "asc" : "desc")}${(keyword == null || keyword.isEmpty) ? "" : "&filter=capital,cs," + keyword}$filtersString"))
.timeout(Duration(
seconds: 10,
));
if (response.statusCode != 200) {
throw Exception("failed to get data from internet");
}
dynamic data = jsonDecode(response.body);
int nbResults = data["results"];
List<DropdownMenuItem> results = (data["records"] as List)
.map<DropdownMenuItem>((item) => DropdownMenuItem(
value: item["capital"],
child:
Text("${item["capital"]} - ${item["country"]} - ${item["continent"]} - pop.: ${item["population"]}"),
))
.toList();
return (Tuple2<List<DropdownMenuItem>, int>(results, nbResults));
},
searchDelay: 500,
futureSearchRetryButton: (Function onPressed) => Column(children: [
SizedBox(height: 15),
Center(
child: ElevatedButton.icon(
onPressed: () {
onPressed();
},
icon: Icon(Icons.refresh),
label: Text("Enter at least 3 characters\n or click to retry")),
)
]),
);
}
} If you wish to keep the item as a full result from the json, you will need to keep the value set as item instead of item["capital"] as follows: import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:search_choices/search_choices.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:http/http.dart';
class SearchCapitals extends StatefulWidget {
const SearchCapitals({
Key? key,
this.width,
this.height,
}) : super(key: key);
final double? width;
final double? height;
@override
_SearchCapitalsState createState() => _SearchCapitalsState();
}
class _SearchCapitalsState extends State<SearchCapitals> {
@override
String? selectedValueSingleDialogPagedFuture;
PointerThisPlease<int> currentPage = PointerThisPlease<int>(1);
Widget build(BuildContext context) {
return SearchChoices.single(
icon: const Icon(Icons.keyboard_arrow_down_rounded),
displayClearIcon: false,
padding: 4,
value: selectedValueSingleDialogPagedFuture,
hint: Text(
"Search capitals",
style: TextStyle(
color: black,
fontWeight: FontWeight.w300),
),
searchHint: Text(
"Search capitals",
style: TextStyle(fontWeight: FontWeight.bold),
),
underline: Container(
height: 0,
),
onChanged: (value) {
setState(() {
selectedValueSingleDialogPagedFuture = value;
});
},
isExpanded: true,
itemsPerPage: 15,
currentPage: currentPage,
selectedValueWidgetFn: (item) {
return DropdownMenuItem(child: (Text(item["capital"])));
},
displayItem: (item, selected) {
return (Row(children: [
selected
? Icon(
Icons.radio_button_checked,
color: Colors.grey,
)
: Icon(
Icons.radio_button_unchecked,
color: Colors.grey,
),
SizedBox(width: 7),
Expanded(
child: item,
),
]));
},
futureSearchFn: (String? keyword, String? orderBy, bool? orderAsc,
List<Tuple2<String, String>>? filters, int? pageNb) async {
String filtersString = "";
int i = 1;
filters?.forEach((element) {
filtersString += "&filter" +
i.toString() +
"=" +
element.item1 +
"," +
element.item2;
i++;
});
Response response = await get(Uri.parse(
"https://corsproxy.io/?https://searchchoices.jod.li/exampleList.php?page=${pageNb ?? 1},10${orderBy == null ? "" : "&order=" + orderBy + "," + (orderAsc ?? true ? "asc" : "desc")}${(keyword == null || keyword.isEmpty) ? "" : "&filter=capital,cs," + keyword}$filtersString"))
.timeout(Duration(
seconds: 10,
));
if (response.statusCode != 200) {
throw Exception("failed to get data from internet");
}
dynamic data = jsonDecode(response.body);
int nbResults = data["results"];
List<DropdownMenuItem> results = (data["records"] as List)
.map<DropdownMenuItem>((item) => DropdownMenuItem(
value: item,
child:
Text("${item["capital"]} - ${item["country"]} - ${item["continent"]} - pop.: ${item["population"]}"),
))
.toList();
return (Tuple2<List<DropdownMenuItem>, int>(results, nbResults));
},
searchDelay: 500,
futureSearchRetryButton: (Function onPressed) => Column(children: [
SizedBox(height: 15),
Center(
child: ElevatedButton.icon(
onPressed: () {
onPressed();
},
icon: Icon(Icons.refresh),
label: Text("Enter at least 3 characters\n or click to retry")),
)
]),
);
}
} But I guess there must be a reason why you chose to set the value as item["capital"]. |
The reason I set value as item["capital"] is what I mention in point 1 of my previous comment. If I set it to just |
Oh, indeed, you explained that. Sorry, I didn't pay enough attention. |
Yep. Appreciate that. Just tried that and it did work. So for now, will make do with this for now. Thank you! |
Great, thanks! |
FYI, I figured out why I was getting that first error with string vs. jsonmap. It was a stupid mistake. You can see above that I have the |
Thank you very much for the explanation @phranklins . I'm glad it is working now fine for you! |
I'm using selectedValueSingleDialogPagedFuture and would like to make items and futureSearchFn look the same just like the ask here: #103. Using the code in the example or the suggested code in the link (selectedValueWidgetFn: (item) {return DropdownMenuItem(child: (Text(item["capital"])));}), I receive the error "Expected a value of type 'int', but got one of type 'String'". If I remove selectedValueWidgetFn, the code works fine.
The text was updated successfully, but these errors were encountered: