Code Monkey home page Code Monkey logo

Comments (11)

lcuis avatar lcuis commented on July 29, 2024

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?

from search_choices.

phranklins avatar phranklins commented on July 29, 2024

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:

  • I removed the filter and sorting options since I don't need them
  • added a proxy to your example URL to make it work in web
  • I removed the web conditions since with the proxy, it should work in web
  • I had to replace value: item, with value: item["capital"],. If I didn't I would receive, the message Error: Expected a value of type 'String', but got one of type '_JsonMap'. That seems expected since you mention it should be a map, but if I left it that way, I always got the error and the only way past it was to change value the way that I did
  • I replaced selectedValueWidgetFn with the code in #103 , but I would receive the error Expected a value of type 'int', but got one of type 'String' regardless of whether I used this code or the code in the example.

Here is basically the code I have for the widget:

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["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")),
        )
      ]),
    );
  }
}

from search_choices.

lcuis avatar lcuis commented on July 29, 2024

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?

from search_choices.

phranklins avatar phranklins commented on July 29, 2024

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:

  1. For code line 98, I receive the error Error: Expected a value of type 'String', but got one of type '_JsonMap' if the line is value: item,. I was able to get passed the error by changing the line to value: item["capital"], As you mentioned, I ideally do want a map and when I look at the data, I see a map. But the error is saying it wants a string, which is why I changed it.
  2. For lines 53-55 for selectedValueWidgetFn, I receive the error Expected a value of type 'int', but got one of type 'String'. Not sure why it's expecting an int since I haven't specified it as such. If I delete these lines, the code works just fine except that the styling doesn't match the other dropdowns in the app.

from search_choices.

lcuis avatar lcuis commented on July 29, 2024

Your code turns the item as in the value: item["capital"], part into a String. It is already the capital.
So, running this code instead worked for me:

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"].

from search_choices.

phranklins avatar phranklins commented on July 29, 2024

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 value: item like you did, I get an error that says Expected a value of type 'String', but got one of type '_JsonMap'

from search_choices.

lcuis avatar lcuis commented on July 29, 2024

Oh, indeed, you explained that. Sorry, I didn't pay enough attention.
Yet, I don't see why you get this issue for now.
Is it fine for you to run with the first solution mentioned in my previous comment?

from search_choices.

phranklins avatar phranklins commented on July 29, 2024

Yep. Appreciate that. Just tried that and it did work. So for now, will make do with this for now. Thank you!

from search_choices.

lcuis avatar lcuis commented on July 29, 2024

Great, thanks!
I hope you don't mind if I close this issue for now.
Don't hesitate to reopen if needed.

from search_choices.

phranklins avatar phranklins commented on July 29, 2024

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 String? selectedValueSingleDialogPagedFuture; which should be dynamic? selectedValueSingleDialogPagedFuture;. I was using selectedValueSingleDialog elsewhere in my code and only replaced the latter half of the this line instead of the updating the whole thing.... Given that, updated the code to reflect that mistake and everything is working as it should.

from search_choices.

lcuis avatar lcuis commented on July 29, 2024

Thank you very much for the explanation @phranklins . I'm glad it is working now fine for you!

from search_choices.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.