State Management With Provider | raywenderlich.com

See how to architect your Flutter app using Provider, letting you readily handle app state to update your UI when the app state changes.


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/6373413-state-management-with-provider
1 Like

Correct me if Iā€™m wrong I have a question. Since the API results are being cache. What can I do to trigger a refresh to get the latest rates?

You could add a button or RefreshIndicator to initiate a manual refresh. Then perhaps add a forceRefresh flag to the fetchExchangeRates() method and handle it there.

1 Like

After this article was published I realized I should have used the ChangeNotifierProvider.value constructor in the last code block.

So change this:

return ChangeNotifierProvider<ChooseFavoritesViewModel>(
      create: (context) => viewModel,

To this:

return ChangeNotifierProvider<ChooseFavoritesViewModel>.value(
      value: viewModel,

The reason is that you are not creating a new view model, but just providing the one you had already created previously in initState().

TODO: Fix this in the next tutorial update.

Hi suragch. Dont know if itā€™s me, but iā€™ve tried to run the start and the final projects and both crashed at the start.

Is it ok to change my viewmodel that on serviceLocator from registerFactory to registerLazySingleton because I want to send events from the services not just from view

Did you ever get it to work? Iā€™ve been meaning to recheck this tutorial, but Iā€™ve been a little swamped with work recently.

Using registerFactory creates a new instance of your view model every time you call it. This is useful if you want to use the same view model code in two different parts of your app. I ran into this recently when I made an app that had two audio players that shared a single view model class. If I had used a singleton for the view model then both audio player widgets would have been modifying the same instance of the view model and neither one would have worked. Since I used separate instances of the view model, they could each manage their own audio widget.

If you only need one instance of a view model, could you use registerLazySingleton? Maybe. Iā€™m not really sure. You could try it, but Iā€™d keep an eye out for bugs. I donā€™t understand your use case so I canā€™t give a great answer. If you are making a service, then registerLazySingleton is how I create services, too. But view models are different than services. They are they controller between the services and the UI.

1 Like

@suragch Thank you for sharing this - much appreciated!

First, thank you for your response.
In my situation, I have a view model that depends on a realtime database (Socket IO), so when my database that on the server change, it sends emit to the client-side in order to rebuild the widgets, and I put the SocketIO as a service.

Although I havenā€™t done any socket IO work myself, if I were approaching this problem, I would make a service to handle the socket IO communication with the server. Iā€™d have that service expose the data it receives from the server as a stream or maybe a callback. Then Iā€™d have the view model listen to the stream from the service. The view model would in turn put the data in a form that could be directly shown in the UI. The view model could also take events from the UI and pass them on to the service by calling some method on the service. In this way the service and the UI never directly interact. Everything is interpreted by the view model. So back to your original question, there is no reason to make your view model a singleton in this case.

Thanks, I will try to make a stream on Socket IO service in order to send events to the view model.

This works like a dream. I got here looking for an alternative to BLoC or rather whether BLoC is replaceable by Provider. This article and the mini-project have helped me immensely. I was intimidated by use of BLoC for a simple thing like Login function which looked overly complex. Provider looked simpler and this article helps greatly. Thanks

1 Like

In learning state management (for flutter/dart development), Iā€™ve been through the setState design and the Provider package; now looking at the BLoC pattern.

BLoC ā€˜feelsā€™ like imposing imperative syntax on a basically declarative (reactive) system, where Provider seem a better fit for the flutter declarative/reactive framework.

I donā€™t have good/bad opinions about this yet, just wondering of those more experienced with flutter/dart have opinions about this (imagined?) distinction

Suppose only parts of the view would need to listen to changes in the ViewModel. Wouldnā€™t this approach cause the entire view to rebuild unnecessarily? If I am wrong please explain why. If my assumptions are correct could you please explain why you used this approach?

You are correct. This is one reason I personally donā€™t use ChangeNotifier any more for state management. Instead, I use ValueNotifier because it only updates the specific component that needs updating. Another problem I had with ChangeNotifier was that I tended to put too much into the class. Itā€™s better to break things into smaller pieces. I describe my current approach to state management here.

That said, an advantage of ChangeNotifier is that itā€™s relatively easy to use and understand. And unless youā€™re making many updates a second, rebuilding a couple extra widgets doesnā€™t really matter much.

Thank you very much for responding when you say ā€œI tended to put too much into the classā€ is the class you are referring to is the ViewModel?. Thanks for the recommendation I definitely take a look.

I am relatively new to state management in flutter and I am starting out with changenotifier as it is easy to grasp before moving on to a different state management solution. What I was thinking to solve this issue is to wrap the widgets in the view I want to update with the Consumer rather than the entire widget. My question was that if putting the Consumer widget within the view would violate the MVVM design pattern. I donā€™t think it will but I wanted to get your opinion on it.

Furthermore, I do like (and follow) your approach with combining certain functionality into services rather than having them in the model or ViewModel. With the introduction of services am I still following the MVVM design pattern (relatively new to employing architecture in application)?

Yes, I used to put too much in the ViewModel.

If I understand your question correctly, then, yes, putting the Consumer as close as possible to the widget than need rebuilding will prevent the entire widget tree (view) from getting rebuilt.

The Consumer widget is a widget, so it belongs in the view, that is, in the UI layer. That doesnā€™t violate MVVM.

As far as I understand it, services are outside of MVVM. They are an addition to it.

Ok thank you for your time really appreciate it

1 Like

I am getting error when I run pub (pubsec.yaml). Please help me!

The error is

[starter] flutter pub get

Running ā€œflutter pub getā€ in starterā€¦

Because no versions of mockito match >4.1.1 <4.1.1+1 and mockito >=4.1.1+1 <4.1.2 depends on test_api >=0.2.1 <0.4.0, mockito >4.1.1 <4.1.2 requires test_api >=0.2.1 <0.4.0.

And because mockito >=4.1.2 <=5.0.0-nullsafety.7 depends on test_api ^0.2.19-nullsafety, mockito >4.1.1 <=5.0.0-nullsafety.7 requires test_api >=0.2.1 <0.4.0.

And because mockito 4.1.1 depends on test_api ^0.2.1 and every version of flutter_test from sdk depends on test_api 0.4.3, mockito >=4.1.1 <=5.0.0-nullsafety.7 is incompatible with flutter_test from sdk.

So, because moolax depends on both flutter_test from sdk and mockito ^4.1.1, version solving failed.

pub get failed (1; So, because moolax depends on both flutter_test from sdk and mockito ^4.1.1, version solving failed.)

exit code 1