Home > Blockchain >  type 'Future<dynamic>' is not a subtype of type 'Future<List<LangModel>
type 'Future<dynamic>' is not a subtype of type 'Future<List<LangModel>

Time:08-29

I want to get a list of languages in my flutter app from my sqflite db, but when I try create the lang list i get this error type 'Future' is not a subtype of type 'Future<List>?'

I tried everything but nothing change, how can i solve the problem?

lang_provider.dart

class LangProvider extends ChangeNotifier{
  List<LangModel> langs = [];

  Future<List<LangModel>> getAllLangs() async{
    Database db = await DBProvider.db.initDB();
    final result = await db.query('languages');

    return result.isNotEmpty ? result.map<LangModel>((langs) => LangModel.fromJson(langs)).toList() : [];
  }

  Future<LangModel?> getLangById(int id) async{
    Database db = await DBProvider.db.initDB();
    final result = await db.query('languages', where: 'id = ?', whereArgs: [id]);

    return result.isNotEmpty ? LangModel.fromJson(result.first) : null;
  }

  loadLangs<LangModel>() async{
    final langs = await getAllLangs();
    this.langs = [...langs];
  }
}

lang_list.dart

    final langProvider = Provider.of<LangProvider>(context, listen: false);
    final langs = <LangModel>[];

    return FutureBuilder<List<LangModel>>(
      future: langProvider.loadLangs(), // <= exception occurs here
      initialData: langs,
      builder: (BuildContext context, AsyncSnapshot snapshot) {
        return Container(
          margin: const EdgeInsets.symmetric(horizontal: 20, vertical: 50),
          child: ListView.builder(
            shrinkWrap: true,
            itemBuilder: (context, i) => ListTile(
              leading: const CircleAvatar(backgroundImage: AssetImage('assets/img/us.webp')),
              title: Text(snapshot.data.language),
              trailing: const Icon(Icons.arrow_forward_ios_outlined),
              onTap: (){
                final route = MaterialPageRoute(
                  builder: (context) => const ScanPageScreen()
                );
                Navigator.push(context, route);
              },
            ),
            // separatorBuilder: (_, __) => const Divider(),
          ),
        );
      },
    );
  }

home_screen.dart

Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
      ),
      body: Column(
        children: const [
          Logo(),
          LangList()
        ]
      ),
    );
  }

lang_model.dart

class LangModel {
    LangModel({
        required this.id,
        required this.flag,
        required this.language,
    });

    int id;
    Uint8List flag;
    String language;

    factory LangModel.fromJson(Map<String, dynamic> json) => LangModel(
        id: json["id"],
        flag: json["flag"],
        language: json["language"],
    );

    Map<String, dynamic> toJson() => {
        "id": id,
        "flag": flag,
        "language": language,
    };
}

CodePudding user response:

I think you want getAllLangs based on your Future.

  future: langProvider.getAllLangs(),

CodePudding user response:

change your loadLangs to this:

Future loadLangs<LangModel>() async{
    final langs = await getAllLangs();
    this.langs = [...langs];
  }

and then your FutureBuilder to this:

FutureBuilder(// remove the generic
  future: langProvider.loadLangs(),
      initialData: langs,
)

second way: just pass langProvider.getAllLangs() to your FutureBuilder.

also change you lang_list.dart to this:

return FutureBuilder(
      future: langProvider.loadLangs(),
      initialData: langs,
      builder: (BuildContext context, AsyncSnapshot snapshot) {
        if (!snapshot.hasData) return CircularProgressIndicator(); // add this
        return Container(
          margin: const EdgeInsets.symmetric(horizontal: 20, vertical: 50),
          child: ListView.builder(
            shrinkWrap: true,
            itemBuilder: (context, i) => ListTile(
              leading: const CircleAvatar(backgroundImage: AssetImage('assets/img/us.webp')),
              title: Text(snapshot.data?.language?? ''), // add this
              trailing: const Icon(Icons.arrow_forward_ios_outlined),
              onTap: (){
                final route = MaterialPageRoute(
                  builder: (context) => const ScanPageScreen()
                );
                Navigator.push(context, route);
              },
            ),
            // separatorBuilder: (_, __) => const Divider(),
          ),
        );
      },
    );
  • Related