Construire une Future<List> à l'initialisation du State. (Provider ?)

Bonjour à tous,

Je bloque sur une étape de mon application et j’aurais besoin de votre aide.

Objectif : J’aimerais avoir une Future<List> lors de mon initState.

Problème : initState ne peut pas retourner un type Future et je ne peux pas utiliser un FutureBuilder() car je veux pouvoir sélectionner toute ou partie de ma liste avec des CheckBox. (avec le setState pour sélectionner ma CheckBox, mon build, et par conséquent, ma liste, se rechargerait à chaque fois que je coche une ligne. C’est pas ce qu’on veut pour l’optimisation :slight_smile: ).

J’ai vue que la meilleure solution serait d’utiliser un Provider. Mais j’ai du mal à le mettre en place…

Avez vous peut-être des solutions plus simple qu’un Provider ? Ou pouvez vous m’aider à comprendre les Provider ^^

Merci d’avance pour votre aide ! :grin:

Hello @AntoLhn,
Pour ma part, je ne gère plus de Future dans mes vues. C’est censé être ton Viewmodel qui récupère la data et ta vue ne fait que récupérer une List récupéré e depuis ton webservice.

Oui mais ca change rien au problème, nan ?

Car dans tout les cas, tu dois construire ta Future<List> à l’initalisation de ton State. Ca déplace juste le problème.

A moins que je me trompe ?! Aurais-tu un example dans ce cas, que je comprenne ta méthode.

Sur ma vue, j’ai une classe abstraite qui me sert d’interface avec mon viewmodel et je définis un getter pour récupérer ma liste.

abstract class IDiscoverViewModel extends ChangeNotifier {
  List<Fungus>? get fungusList;
}

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: const Text("Découvrir les champignons"),
      ),
      body: SafeArea(
        child: AnimatedBuilder(
            animation: _viewModel,
            builder: (context, child) {
              final fungusList = _viewModel.fungusList;

Sur mon viewmodel, j’ai encore une interface vers le router et mon getter qui est défini :

abstract class DiscoverRouter {
  fungusDetail({required int fungusId});
}

class DiscoverViewModel extends IDiscoverViewModel {
  final DiscoverRouter _router;
  final List<Fungus> _fungusList;

  DiscoverViewModel(this._router, this._fungusList);

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

}

et dans mon router, au lancement de l’app, je déclenche l’appel à mon webservice :

@override
  Future<void> setNewRoutePath(NavigationPath configuration) async {
    final fungusId = configuration.fungusId;
    if (fungusId != null) {
      final fungus = await _fungusManager.getFungusDetail(fungusId: fungusId);
      if (fungus != null) {
        _fungus = fungus;
      }
    } else {
// Récupération de la liste
      _fungusList = await _fungusManager.getFungusDiscover();
    }
  }

Je ne sais pas si tu as visionné le cours sur le router / navigation 2.0 mais tu auras tous les détails pour gérer cette classe particulière.

3 « J'aime »

Ah d’accord je vois. Vraiment propres comme ça effectivement ! Je vais sûrement faire de cette manière.

Merci pour ton aide et ta solution ! :pray:t3:

C’est beau à voir :star_struck: Tu as parfaitement saisi la logique d’organisation @Tazooou ! Je ne sais pas pour toi, mais depuis que j’organise mon projet comme ça, tout me paraît simple à mettre en place

1 « J'aime »

Ce dernier cours, c’est la fameuse pièce qui te permet de mieux appréhender la vue d’ensemble du puzzle :slight_smile: Il me manquait quelque chose entre la théorie des objets des premiers cours et ce que j’implémentais dans mon projet. Maintenant, tout est plus simple et plus clair !

1 « J'aime »

Hello @Tazooou . Excuse moi, de revenir un peu plus tard j’ai pas retravailler sur l’app depuis.

Il y’a un deux petite chose que je comprend pas bien.

  • Comment j’affecte ma liste à mon getter IDiscoverViewModel ?
  • Et je comprend pas trop ton DiscoverViewModel Pourquoi tu lui passe une route et du coup ton appel de ta vue DiscoverView se fait comment ?

Mise en application

  • Ma vue :
abstract class DealScreenModel extends ChangeNotifier {
  List<Deal?> get dealsList;
}

class DealsScreen extends StatefulWidget {
  final DealScreenModel screenModel;
  const DealsScreen({Key? key, required this.screenModel}) : super(key: key);

  @override
  State<DealsScreen> createState() => _DealsScreenState(screenModel);
}

class _DealsScreenState extends State<DealsScreen> {
  final DealScreenModel screenModel;
  List<Deal?> listDeals = [];

  _DealsScreenState(this.screenModel);

  @override
  void initState() {
    super.initState();
    listDeals = screenModel.dealsList;
  }

  @override
  Widget build(BuildContext context) {
  return ...
  • Ma vue model :
abstract class DealRoutes {
  listDeals();
}

class DealViewModel extends DealScreenModel {
  final DealRoutes _routes;
  final List<Deal?> _dealsList;

  DealViewModel(this._routes, this._dealsList);

  @override
  List<Deal?> get dealsList => _dealsList;
}
  • Mon router :
class RouteGenerator {
  Future<void> setRoute() async {
    List<Deal?> dealsList = await HttpDeal().httpTableDeals();
  }

  static Route<dynamic> generatorRoute(RouteSettings settings) {
    // final args = settings.arguments;

    switch (settings.name) {
      case '/':
        return MaterialPageRoute(builder: (context) => const LoginScreen());
      case '/deals':
        return MaterialPageRoute(builder: (context) => DealsScreen(screenModel: /*screenModel*/ ));

Hello @AntoLhn,

Pour ta liste, tu y accèdes via ton viewmodel.

Au niveau de ta vue, tu pourras appeler ta liste avec « screenModel.dealsList »

Le getter c’est juste pour éviter toute modification en dehors du viewmodel.

Pour le router, c’est un peu plus complexe. Ma navigation n’est pas réalisée directement dans un écran mais à l’intérieur d’une classe spécifique qui s’occupe que de la navigation.

Pour aller de mon écran 1 vers le 2, je vais envoyer un évènement vers mon router pour lui dire de créer l’écran 2.

Maxime a fait tout un cours la dessus, je ne pourrais ni même ne saurais te résumer ça en un post :slight_smile:

Si tu as accès à la formule, je te recommande fortement de le suivre, on y apprend plein de trucs !!

N’hésites pas si tu as encore des questions !