0

I am trying to use the ViewModelWidget class from the stacked package. I am able to show the TextWidget which extends ViewModelWidget in the body of the page, but cannot show it in the bottom sheet because I am showing the bottom sheet from the onPressed function and that function does not have access to the view model.

Here is the code:

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Flutter Demo',
      home: MyView(),
    );
  }
}
class MyViewModel extends BaseViewModel {
  String title = 'Hello';

  void updateTitle() {
    title = 'Bye';
    notifyListeners();
  }
}
class MyView extends StatelessWidget {
  const MyView({super.key});

  @override
  Widget build(BuildContext context) {
    return ViewModelBuilder<MyViewModel>.reactive(
      viewModelBuilder: () => MyViewModel(),
      builder: (context, model, child) => Scaffold(
        appBar: AppBar(
          title: const Text('My View'),
        ),
        body: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            const TextWidget(),
            ElevatedButton(
              onPressed: () {
                showModalBottomSheet<void>(
                  context: context,
                  builder: (BuildContext context) {
                    return const SizedBox(child: Center(child: TextWidget(),), height: 200,);
                  },
                );
              },
              child: const Text('Show Modal'),
            ),
          ],
        ),
      ),
    );
  }
}

class TextWidget extends ViewModelWidget<MyViewModel> {
  const TextWidget({super.key});

  @override
  Widget build(BuildContext context, MyViewModel viewModel) {
    return Text(viewModel.title);
  }
}

And here's the error that happens when I try to open the bottom sheet:

enter image description here

How can I solve this error?

B Faley
  • 17,120
  • 43
  • 133
  • 223
  • hi, instead of calling TextWidget() as a viewmodel widget, you can pass the value from textwidget, and use as a normal widget. for ex => TextWidget(model.title) and showthat inside the widget. – Kani Raj Dec 12 '22 at 11:53
  • class TextWidget extends StatelessWidget { TextWidget(this.title); final String title; @override Widget build(BuildContext context) { return Container( child: Text(title), ); } } – Kani Raj Dec 12 '22 at 12:07
  • why updateTitle is never called ? shouln't be onModelReady: (viewModel) => viewModel.updateTitle(), what about BaseViewModel ? it should extends ChangeNotifier – Zhar Dec 12 '22 at 14:45

1 Answers1

0

I think i got it

The .nonReactive constructor is best used for providing your ViewModel to multiple child widgets that will make use of it. It was created to make it easier to build and provide the same ViewModel to multiple UI's. It was born out of the Responsive UI architecture where we would have to provide the same ViewModel to all the different responsive layouts.

As a result you should give a try to return ViewModelBuilder<HomeViewModel>.nonReactive(

Check the doc #Non Reactive : https://pub.dev/packages/stacked

Zhar
  • 3,330
  • 2
  • 24
  • 25