Home > Net >  Flutter: Error in Future<List<dynamic>> type
Flutter: Error in Future<List<dynamic>> type

Time:09-30

I'm pretty new to Flutter and I've come across an issue when working with Future types. Basically, I'm trying to develop a simple search engine that displays books which have the query string in the title in a List View. Using Future Builder, I get a list with all the books from a raw JSON file and, if the snapshot has data, I pass it through the searchBooks function, that takes in the query string and gather the search results in an array. Finally, I would pass the book data to the bookCard function that actully builds the display.

The issue I've been having is that I can't work with the snapshot data because Class 'Future<List<dynamic>>' has no instance of method '[]'.

How would I go about fixing this?

Here is the JSON data I've beeen working with, for reference: https://raw.githubusercontent.com/a-starck02/book_data/main/bookData_complex.json

Here is the part of the code that is throwing the error:

  @override
  Widget build(BuildContext context) {
    return Container(
      height: MediaQuery.of(context).size.height,
      child: ListView.separated(
        scrollDirection: Axis.vertical,
        separatorBuilder: (context, index) => SizedBox(width: 8),
        itemCount: 15,
        **itemBuilder: (BuildContext context, int index) => FutureBuilder(
            future: userBooksAll,
            builder: (BuildContext context, AsyncSnapshot snapshot) {

              if(snapshot.hasData) {

                searchBooks(query) async {
                  var searchResults = [];
                  for(var i = 0 ; i <= snapshot.data.length ; i  ) {
                    if(snapshot.data[i].title.toLowerCase().contains(query.toLowerCase())) {
                      searchResults.add(snapshot.data[i]);
                    }
                  };

                  return searchResults;
                }

                var searchResults = searchBooks(query);

                return bookCard(context, searchResults, index   factor);**
              } else {
                return Container(
                  child: Center(
                    child: Padding(
                      padding: const EdgeInsets.all(10.0),
                      child: CircularProgressIndicator(),
                    ),
                  ),
                );
              }
            }
        ),
      ),
    );
  }

CodePudding user response:

In dart, only Maps {"key":"value"} have the [] property, for accessing key, value pairs like somemap["key"]["value"] For lists the value at the index somelist[index]

This might help https://flutter.dev/docs/cookbook/networking/fetch-data#4-fetch-the-data

CodePudding user response:

Answer

So, the issue that I was having was that the searchBooks function was async so, naturally, it would return another Future value. It was a pretty silly mistake that I only realized after completely rewriting the code two times.

Anyway, thanks for everyone who spent time thinking about an answer. Here is the final reformatted working code:

  @override
  Widget build(BuildContext context) {

    var itemCount = 0;

    return Container(
      height: MediaQuery.of(context).size.height,
      child: FutureBuilder(
          future: userBooksAll,
          builder: (BuildContext context, AsyncSnapshot snapshot) {
            if(snapshot.hasData) {
              bookSearch(query) {
                var searchResults = [];
                for (var i = 0; i <= snapshot.data.length - 1 ; i  ) {
                  if (snapshot.data[i].title.toLowerCase().contains(
                      query.toLowerCase())) {
                    searchResults.add(snapshot.data[i]);
                  }
                }
                itemCount = searchResults.length;
                return searchResults;
              }

              var searchResults = bookSearch(query);

              return ListView.separated(
                scrollDirection: Axis.vertical,
                separatorBuilder: (context, index) => SizedBox(width: 8),
                itemCount: itemCount,
                itemBuilder: (BuildContext context, int index) => bookCard(context, searchResults, index)
              );

            } else {
              return Container(
                child: Padding(
                  padding: const EdgeInsets.all(10.0),
                  child: CircularProgressIndicator(),
                ),
              );
            }
          }
        )
      );
  }
  • Related