skip to Main Content

The data coming from the view model is supposed to be listened in the view, and the setState make it rebuild.

The refresh is correct with the child widget (secondChildWidget) but it’s not updating with the modal one inside the onTap closure (firstChildWidget).

How to make it update ?

Both are stateless.

This is my code:

class MyView extends StatefulWidget {
  const MyView({super.key});

  @override
  State<MyView> createState() => _MyViewState();
}

class _MyViewState extends State<MyView> {

    final ViewModel viewModel = ViewModel();

    String item = "";

    @override
    void initState() {
        super.initState();
        viewModel.item.listen((value) {
           setState(() { 
              item = value;
           });
        });
     }

    @override
    Widget build(BuildContext context) {
        return GestureDetector(
            onTap: () {
            showModalBottomSheet(
                isScrollControlled: true,
                context: context,
                builder: (context) {
                    return firstChildWidget(item);
                });
             },
            child: secondChildWidget(item),
          );
     }
}

3

Answers


  1. To fix this, use ‘StatefulBuilder’ inside the modal.

    class MyView extends StatefulWidget {
      const MyView({super.key});
    
      @override
      State<MyView> createState() => _MyViewState();
    }
    
    class _MyViewState extends State<MyView> {
      final ViewModel viewModel = ViewModel();
      String item = "";
    
      @override
      void initState() {
        super.initState();
        viewModel.item.listen((value) {
          setState(() {
            item = value;
          });
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return GestureDetector(
          onTap: () {
            showModalBottomSheet(
              isScrollControlled: true,
              context: context,
              builder: (context) {
                return StatefulBuilder(
                  builder: (context, setModalState) {
                    return firstChildWidget(item);
                  },
                );
              },
            );
          },
          child: secondChildWidget(item),
        );
      }
    }
    

    The issue is that ‘firstChildWidget’ is not updating because it’s built only once when the ‘showModalBottomSheet’ is triggered.

    Login or Signup to reply.
  2. showModalBottomSheet is stateless widget by default. If you wrap the child of showModalBottomSheet by stateful builder it may resolve your issue

    class MyView extends StatefulWidget {
    
    
    const MyView({super.key});
    
      @override
      State<MyView> createState() => _MyViewState();
    }
    
    class _MyViewState extends State<MyView> {
      final ViewModel viewModel = ViewModel();
    
      String item = "";
    
      @override
      void initState() {
        super.initState();
        viewModel.item.listen((value) {
          setState(() {
            item = value;
          });
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return GestureDetector(
          onTap: () {
            showModalBottomSheet(
                isScrollControlled: true,
                context: context,
                builder: (context) {
                  StatefulBuilder(builder: (context, setState) {
                    return firstChildWidget(item);
                  },)
                });
          },
          child: secondChildWidget(item),
        );
      }
    }
    
    Login or Signup to reply.
  3. You are instantiating a new Viewmodel instance by writing

    final ViewModel viewModel = ViewModel();
    

    I’m guessing that this viewmodel’s item is never being changed.
    I’m assuming that the instance that actual has changes is another one.
    It’s hard to tell how to solve it because it depends on the rest of your project. You need to look into state management in order to understand how to do this. It might simply work by making the item inside the viewmodel static but in general that’s a bad approach, especially if you need multiple instances of this model.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search