Future<dynamic>' is not a subtype of type '(() => void)?

Hello tout le monde,

J’ai un crash au lancement de mon application que je n’arrive pas à résoudre.
Pour l’instant, j’ai un seule vue avec un ListView.builder et un bouton de chargement. Au tap sur le bouton, cela déclenche normalement le chargement de la liste du ListView.
Problème, je n’ai même pas le temps d’appuyer sur le bouton que l’application se crashe avec cette erreur :

Une exception s est produite.
_TypeError (type 'Future<dynamic>' is not a subtype of type '(() => void)?')

Je vous mets le code de ma vue ci dessous :

abstract class IDiscoverViewModel extends ChangeNotifier {
  List<Fungus> get fungusList;
  fungusDiscover();
}

class DiscoverView extends StatelessWidget {
  final IDiscoverViewModel _viewModel;
  const DiscoverView(this._viewModel, {Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Découvrir les champignons"),
      ),
      body: SafeArea(
        child: AnimatedBuilder(
            animation: _viewModel,
            builder: (context, child) {
              final fungusList = _viewModel.fungusList;
              return Column(
                children: [
                  if (fungusList.isNotEmpty)
                    ListView.builder(
                        itemCount: fungusList.length,
                        itemBuilder: (BuildContext context, int index) {
                          return DiscoverCellWidget(fungus: fungusList[index]);
                        }),

                  // Bouton de Chargement
                  Row(children: [
                    const Spacer(),
                    ElevatedButton(
                        onPressed: _viewModel.fungusDiscover(),
                        child: Text("Charger la liste")),
                    const Spacer()
                  ]),
                ],
              );
            }),
      ),
    );
  }
}
abstract class IFungusManager {
  Future<List<Fungus>> getFungusDiscover();
}

class DiscoverViewModel extends IDiscoverViewModel {
  final IFungusManager _manager;
  DiscoverViewModel(this._manager);

  List<Fungus> _fungusList = [];

  @override
  List<Fungus> get fungusList => _fungusList;

  @override
  fungusDiscover() async {
    final fungusList = await _manager.getFungusDiscover();
    _fungusList = fungusList;
    notifyListeners();
  }
}

J’ai tenté de mettre des points d’arrêt dans mon code et le crash se produit dans ma fonction de login à l’étape où j’effectue mon http.post :

final response = await http.post(url,
        headers: <String, String>{
          'Content-Type': 'application/json; charset=UTF-8',
        },
        body: json);
    if (response.statusCode == 200) {
      final loginResponse = LoginResponse.fromJSON(jsonDecode(response.body));

      accessToken = loginResponse.data.accessToken;
      refreshToken = loginResponse.data.refreshToken;
      expireAccessTokenDate = DateTime.now().add(const Duration(minutes: 14));
      expireRefreshTokenDate = DateTime.now().add(const Duration(days: 7));
    } else {
      throw Exception("Login invalide");
    }

Je ne comprends pas bien comment il rentrer dans cette fonction sans que j’ai pu appuyer sur le bouton et cette fonction de login fonctionnait très bien avant que je positionne mon ListView …

Si vous avez des idées pour m’aider à résoudre ce problème, ce serait top !!

Merci d’avance.

Salut @Tazooou

De ce que je comprends :
le onPressed: demande un retour type void, sauf que la fonction fungusDiscover est un async, et donc du type Future<dynamic>.
Tu peux essayer de le wrapper dans une closure éventuellement du genre :
onPressed: () => _viewModel.fungusDiscover()pour répondre à la demande de Flutter.

Hello Martin,

Bien vu :wink:

C’est les parenthèses qui posaient problème et qui lançaient le chargement !!

J’ai modifié par ce bout de code :

onPressed: _viewModel.fungusDiscover,

Merci pour ton aide précieuse :+1:

1 « J'aime »

Dommage que le compilateur ne dise rien avant le lancement, ça m’aurait épargné pas mal de temps :smiley:

Effectivement, encore plus simple !
Je crois que Maxime en parle dans ses cours en plus… :sweat_smile:

Je te confirme :slight_smile: mais je pensais pas que c’était une obligation de les enlever !!

on comprend qu’une fois qu’on a l’erreur. C’est connu. :sweat_smile:

1 « J'aime »