0
votes

I am getting the following error :

The following _TypeError was thrown building FutureBuilder(dirty, state: _FutureBuilderState#0e8bb): type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Comparable'

When what I am trying to do is to build a Listview using FutureBuilder from a local Json and then sort the items if user taps on menu to sort :

class _ResultScreenState extends State<ResultScreen> {
  List showData;
  var sortedData;
  bool byName = false;
  bool byRating = false;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        ConstrainedBox(
          constraints: const BoxConstraints.expand(),
          child: Image(
            fit: BoxFit.cover,
            image: AssetImage('assets/scuba.jpg'),
          ),
        ),
        Scaffold(
          appBar: AppBar(
            title: Text("Scuba Dive"),
            actions: <Widget>[
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: Center(child: Text("Sort By")),
              ),
              PopupMenuButton<String>(
                icon: Icon(
                  Icons.sort,
                  size: 32,
                ),
                onSelected: choiceAction,
                itemBuilder: (BuildContext context) {
                  return Constants.choices.map((String choice) {
                    return PopupMenuItem<String>(
                      value: choice,
                      child: Text(choice),
                    );
                  }).toList();
                },
              )
            ],
          ),
          body: Container(
            constraints: BoxConstraints.expand(),
            decoration: BoxDecoration(
                image: DecorationImage(
                    image: AssetImage('assets/scuba.jpg'),
                    colorFilter:
                        ColorFilter.mode(Colors.black26, BlendMode.darken),
                    fit: BoxFit.cover)),
            child: FutureBuilder(
              builder: (context, snapshot) {
                showData = json.decode(snapshot.data.toString());

                if (byName) {
                  showData.sort();
                }

                return ListView.builder(
                  itemBuilder: (BuildContext context, int index) {
                    return Container(
                      padding: EdgeInsets.all(8),
                      margin: EdgeInsets.all(12),
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(8),
                        color: Colors.white70,
                      ),
                      child: Column(
                        children: <Widget>[
                          Row(
                            children: <Widget>[
                              ConstrainedBox(
                                constraints: BoxConstraints(
                                  maxWidth: 150,
                                  maxHeight: 80,
                                ),
                                child: Image(
                                  image: AssetImage(showData[index]["image"]),
                                ),
                              ),
                              Flexible(
                                child: Padding(
                                  padding: const EdgeInsets.all(8.0),
                                  child: Column(
                                    crossAxisAlignment:
                                        CrossAxisAlignment.start,
                                    children: <Widget>[
                                      Text(
                                        showData[index]["name"].toString(),
                                        style: TextStyle(
                                            fontSize: 18,
                                            fontWeight: FontWeight.bold),
                                      ),
                                      Text("Rating : " +
                                          showData[index]["rating"]),
                                    ],
                                  ),
                                ),
                              ),
                            ],
                          ),
                        ],
                      ),
                    );
                  },
                  itemCount: showData == null ? 0 : showData.length,
                );
              },
              future:
                  DefaultAssetBundle.of(context).loadString("assets/data.json"),
            ),
          ),
        )
      ],
    );
  }

  void choiceAction(String choice) {
    if (choice == Constants.FirstItem) {
      setState(() {
        byName = true;
      });
    } else if (choice == Constants.SecondItem) {
      print("Second");
    }
  }
}

What could be the reason and how can I fix it?

1
Can you provide an example json which you use? - NiklasLehnfeld
Off-topic : itemCount: showData == null ? 0 : showData.length, can be written itemCount: showData?.length ?? 0, for consistency. - Augustin R
Example of jsonData :{ "name" : "Lizard Island", "image" : "assets/Lizard-Island.jpg", "rating" : "8.7" }, - user3748198

1 Answers

1
votes

The error comes from this line :

showData.sort();

Because json.decode does not return a Comparable. You should consider giving a type to showData (which could be a local variable) :

List<Data> showData = List<Data>.from(json.decode(snapshot.data.toString()));