The return type 'Future<Image>' isn't a 'Widget', as required by the closure's context

9,448

There is a mistake in the use of your nested FutureBuilder. Rather than using the snapshot in the FutureBuilder builder, you are calling the recentAlbumArt again and returning that.

if (data.hasData) {
  return recentAlbumArt(//CALLING recentAlbumArt AGAIN HERE
    albums[index].coverArt)
      .then((coverArtList) {
        return Image.network(coverArtList[index]);
      });
}

Instead use the snapshot that the FutureBuilder provides.

if (data.hasData) {
  return Image.network((data.data)[index]);
}
Share:
9,448
limitlessbritt
Author by

limitlessbritt

Updated on December 21, 2022

Comments

  • limitlessbritt
    limitlessbritt over 1 year

    I'm sending login info to an api and getting a image id number that I send back to the api to get the image and i want to display the images in a grid but i'm getting a "The return type 'Future' isn't a 'Widget', as required by the closure's context." error.

    the error is on the recentAlbumArt function

    import 'package:flutter/material.dart';
    import 'package:test_music_app/API/api_call.dart';
    
    import 'package:test_music_app/API/auth.dart';
    
    class RecentlyAddedAlbums extends StatefulWidget {
      @override
      _RecentlyAddedAlbumsState createState() => _RecentlyAddedAlbumsState();
    }
    
    class _RecentlyAddedAlbumsState extends State<RecentlyAddedAlbums> {
      Future<List<Album>> albums;
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Container(
            child: FutureBuilder(
                future: fetchRecentlyAddedAlbums(),
                builder: (context, AsyncSnapshot<List<Album>> data) {
                  switch (data.connectionState) {
                    case ConnectionState.none:
                      return Text(
                        "none",
                        style: TextStyle(color: Colors.black),
                      );
                    case ConnectionState.waiting:
                      return Center(
                          child: CircularProgressIndicator(
                        valueColor: AlwaysStoppedAnimation<Color>(Colors.black),
                      ));
                    case ConnectionState.active:
                      return Text('');
                    case ConnectionState.done:
                      if (data.hasData) {
                        List<Album> albums = data.data;
                        return ListView.builder(
                          itemCount: albums.length,
                          itemBuilder: (context, index) {
                            return FutureBuilder(
                                future: recentAlbumArt(albums[index].coverArt),
                                builder: (context, AsyncSnapshot data) {
                                  switch (data.connectionState) {
                                    case ConnectionState.none:
                                      return Text(
                                        "none",
                                        style: TextStyle(color: Colors.black),
                                      );
                                    case ConnectionState.waiting:
                                      return Center(
                                          child: CircularProgressIndicator(
                                        valueColor: AlwaysStoppedAnimation<Color>(
                                            Colors.black),
                                      ));
                                    case ConnectionState.active:
                                      return Text('');
                                    case ConnectionState.done:
                                      if (data.hasData) {
                                        return recentAlbumArt(
                                                albums[index].coverArt)
                                            .then((coverArtList) {
                                          return Image.network(coverArtList[index]);
                                        });
                                      }
                                  }
                                });
                          },
                        );
                      }
                  }
                }),
          ),
        );
      }
    }
    
    

    the two functions:

    Future<List<Album>> fetchRecentlyAddedAlbums() async {
      try {
        var salt = randomToken(6);
        var token = makeToken("$password", "$salt");
        var uRL =
            "$server/rest/getAlbumList?u=$username&t=$token&s=$salt&v=$tapeOutVerison&c=$client$format&type=newest";
        var authresponse = await http.get(uRL);
        if (authresponse.statusCode == 200) {
          var jsondata = jsonDecode(authresponse.body);
          var data = apicallFromJson(jsondata);
          var aresponse = data.subsonicResponse.albumList.album;
          return aresponse;
        } else {
          return null;
        }
      } catch (e) {
        return null;
      }
    }
    
    //TODO: build the cover art fetching within the album list or build it outside
    Future recentAlbumArt(String coverArtID) async {
      try {
        var salt = randomToken(6);
        var token = makeToken("$password", "$salt");
        var uRL =
            "$server/rest/getCoverArt/?u=$username&t=$token&s=$salt&v=$tapeOutVerison&c=$client$format&id=$coverArtID";
        var coverArtList = await http.get(uRL);
        return coverArtList;
      } catch (e) {
        print(e);
      }
    }
    
  • limitlessbritt
    limitlessbritt almost 4 years
    Thanks! Another question it says "Class 'Response' has no instance method '[]'." is that related to the response of http request? I don't have a class called response.
  • Christopher Moore
    Christopher Moore almost 4 years
    Yes it's related to the response of the http request. You're likely trying to call something on it that doesn't exist for the object type. I recommend creating a separate question for this.