Home > database >  Futurebuild with dynamic list
Futurebuild with dynamic list

Time:01-07

I have a function that takes some json and puts the entire object into a dynamic list. I am having trouble looping over that list using the futurebuilder. I always get "the getter 'length' isn't defined for the class 'Future<List>" error. same for the title.

What is the correct way to do this? To access this list in a futurebuilder or listbuilder.

Thanks alot in advance.

  class _HomeScreenState extends State<HomeScreen> {
      final storage = new FlutterSecureStorage();

      Future<List<dynamic>> _loadedProducts;
       @override
      void initState() {
     _loadedProducts = _getPolicy();
      super.initState();

 }


  Future<void> _getPolicy() async {
  final url = Uri.parse('https://jsonplaceholder.typicode.com/todos/1');

try {
  final response = await http.get(url);
  final extractedData = json.decode(response.body);


  final List<dynamic> loadedProducts = [];
  extractedData.forEach((prodId, prodData) {
    loadedProducts.addAll(extractedData);
  });
 
   _loadedProducts = loadedProducts;
   print(_loadedProducts);
 

} catch (error) {
  print('---error-');
  throw (error);
}

}

Here is the code for the futurebuilder

FutureBuilder<List<dynamic>>(
            future: _loadedProducts,
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return AnimatedList(
                  initialItemCount: snapshot.data.length,
                  itemBuilder:
                      (BuildContext context, int index,
                      Animation animation) {
                    return new Text(_loadedProducts.title.toString());
                  },
                );
              } else if (snapshot.hasError) {
                return Text("${snapshot.error}");
              }

              // By default, show a loading spinner.
              return CircularProgressIndicator();
            },
          );

CodePudding user response:

You need to return the list in your _getPolicy() future function. So try changing it like so:

  Future<List<dynamic>> _getPolicy() async {
    final url = Uri.parse('https://jsonplaceholder.typicode.com/todos');

    try {
      final response = await http.get(url);
      return json.decode(response.body);

    } catch (error) {
      print('---error-');
      rethrow;
    }
  }

What I changed: In your url, you are only getting one todo, so I removed /1 from your url. If instead you want to get all todos of the user with userId=1 then you can change the url to the following

https://jsonplaceholder.typicode.com/todos?userId=1

Also, the json.decode() already returns a list, so no need for your forEach

Moreover, you need to fix the text widget in your animated list as you can't use _loadedProducts.title. You need to use the snapshot data here. This is your FutureBuilder code after a few fixes:

    FutureBuilder<List<dynamic>>(
      future: _loadedProducts,
      builder: (context, AsyncSnapshot<List<dynamic>> snapshot) {
        if (snapshot.hasData && snapshot.data != null && snapshot.data!.isNotEmpty) {
          return AnimatedList(
            initialItemCount: snapshot.data!.length,
            itemBuilder:
                (BuildContext context, int index,
                Animation animation) {
              return new Text(snapshot.data![index]['title']);
            },
          );
        } else if (snapshot.hasError) {
          return Text("${snapshot.error}");
        }

        // By default, show a loading spinner.
        return CircularProgressIndicator();
      },
    );

Here's a working demo

  •  Tags:  
  • Related