Yes bug is fixed but wait, what is it ''HomeModel was used after being disposed of.'' How it was disposed of??? we never disposed of HomeModel. Please explain this, It is huge confusion
@@aminefarhat8382 It's my pleasure, thanks for watching. These principles applies to the new stacked package as well, the only diffrence is I built all the viewmodel code in there so you don't have to :)
Months ago, I watched this tutorial and had no clue what was going on even though I understood how to use provider. Now I understand every piece of code and reason behind it after gaining more experience in Dart & Flutter. In summary, this is not a beginners video, so don't get overwhelmed. Level up and rewatch in a few month or year or however long it takes for you and comeback. Good job FiiledStacks!
WOW! So I started to learn flutter 3 weeks ago and the last 2 days I was working on an App where I wanted to target exactly the same problem as you did (provider, state management). And its so funny because you built almost exact the same app structure as I did. Even our folder structure is similar and we call the stuff same. Really funny how coders have the same mindset. Btw: You did not only taught people how to use provider and state management, you also taught us how to structure a large app and keep a nice architecture. THATS GOLD and SO useful. Btw I usually never comment on videos but you really deserve it. Take my sub!
I really appreciate your comment and thank you for taking the time to write it. It means a lot to me that you get value out of this and that you're learning from it. Thank you for the subscription and the feedback. I really appreciate it 🙏
@@FilledStacks I was wondering about one thing though which confuses me. Let's say you have a number in ur post widget and you can increase it on-click. Now you wanna see it on the PostView page to, when you navigate there. How would you achieve that in this architecture? Im confused because you have a list of posts. When we call Proivder.of it doesnt expect a specific list item... so I dont know how to achieve this.
@@cloud15487 If your Post widget has logic in it then I would create a Model for it and increase the number in there. I would keep my app data in a service called information service that has a list of all the posts. When I update one I'll go that list, manipulate it and save it locally (i you want it saved) and then when navigating I will now instead pass the post index, then retrieve the post information from the information service (which always has the updated post) and then display the information using the data on the data.
@@FilledStacks I am trying to achieve this right now but im not able to :( is there any chance you can provide an example in your Github Repo? What I want to achieve is following: - Add a state to the post_list_item (e.g. a number) - Add a button on it - Everytime I press the button, the number is being incremented in HomeView and PostView. - Warning: It can be incremented from the HomeView AND from the PostView. I managed to implement it "one-way". If I increment it from HomeView, it works. I can see the change in the PostView too. But if I increment it from PostView, I cant see it in HomeView. I need the "navigator.pop" event to refetch the data from HomeView or something similar. Thats the issue I'm having. :(
The problem is, that whenever I pop back from PostView to HomeView, it will not update my HomeView. Its only updating it in "onModelReady" which refreshes the model in "InitState". That is the main problem I have when I use this architecture. Im sure there is a nice way to solve this, but I've tried for a few hours and im not getting anywhere. Right now I have implemented a button in the HomeView with " onPressed: () {model.getPosts();}" to synchronize the changes made in PostView with HomeView. But this is a very ugly solution as u would agree probably. I'd appreciate any help...
Brilliant! I have read medium posts, watched youtube videos and one paid for tutorial and could not get my head around the concept. I read your article, watched your video and it all falls into place. Not just how it works but how it all fits together in the Flutter framework. Thank you very much.
You're very welcome John. I had the same problem when I started in flutter. That's the reason I started my channel. There were no clear guides to do anything in terms of architecture. Bloc didn't work for me so when I came up with this for a client app I figured I'd share it with the rest of the community.
thank you for the comment. And thank you for letting me know that it helped you. I appreciate it. Check out the latest stacked architecture videos, it's the newer version of this video that you're watching.
Can We agree that this architecture needs to be the number ONE recommended architecture on FlutterDev? @FilledStacks is using Provider (Recommended state management technique), so this architecture could be the Recommended way to structure our apps. No craziness, easy to follow, easy to implement, easy to maintain. How do we make this happen?
Haha I like the positivity and support for the architecture. I agree that it's probably the easiest way to get into any kind of architecture that would provide a solid base for all size applications. I think one way for use to get it published or recommended is for you to share it as much as possible. And I'm not fishing for views, I think the flutter devs are very active in the community so the more they see something the bigger they know the impact is. Remi was found in the community for provider, and the more it was seen the more they worked it into their apps and then finally adopted it. Bloc was the same way until they let go of that. So i think sharing the video, writing your own articles about the setup,improving it, expanding on it, sharing the flaws of it, etc. Until we have a solid solid solid architecture that we can all be proud of. I'm just laying the base but there's lots I still need to add to it and explain before it's "complete".
@@FilledStacks Nice. I'm working on different projects (3 of them to be shipped next year) and I'm using this architecture. I'll try to create content for the Latin American community using this architecture (Probably help you out by adding Spanish captions to this video).
Legends!! Exactly what i've been searching for days.. Well done guys! please keep up the great posts :) Coming from Mvvm in Xamarin this structure brings in alot of the architecture and best practices I've come to appreciate and value
Thank you for the great feedback. I'm a Xamarin developer myself coming from MvvmCross so this makes is heavily inspired by that :) I'm happy you could see the link.
Hello Dane, first of all i've been watching your tutorials lately and i find them the best, thanks man! I have a question, i used the same way you mentioned in this video to build my flutter APP that deals with an API i made, i face a problem that the first time i open the APP the user id entered is not taken in consideration, instead initial value is used (0), then going back to login and login again dose the magic. I suspect the StreamProvider dosen't supply User to homeview on the first time. I tried a lot, the values stuck on 0 as a first time. any thoughts please?
I think i figured it out :) After some reading in the provider documentation i found out that create callback is lazy-loaded which means it's called the first time the value is read instead of the first time the provider is created, that was giving me first just the initial data (0 in our case). The solution was just to set lazy to false inside the StreamProvider.
@@hasanimam82 thanks for commenting the solution as well. It helps the other devs that might be dealing with the same things. Thanks also for checking out the videos and typing up some feedback, I really appreciate it.
Excellent video, however, I have a few suggestions to make it better: 1) use interfaces for the services. It's needed when you start making tests, or even during development, sometimes we want a mocked service registered to work on something we want specifically to work with (let's say, edge cases). 2) for a viewstate you might need specific states per page, in this case I use an enum per page and a single boolean for "isBusy" doesn't change too much of what you did and gives the flexibility to add more than 2 stages. So, if isBusy is true, the view is busy, otherwise it is idle however, the page's state can be anything depending on your app's logic (in my case, I have an upload button that creates a state "uploading" which will add a small message, however, the page is not busy, I can still use the rest of it except for the upload button). Now, a couple of questions' Isn't the provider rebuilding the whole page? I mean, I don't need to rebuild the login title, but when it triggers the setState, isn't it rebuilding it? I know is not much, just one text, but image that this page has a lot more that I don't want to rebuild, how should I handle this?
Excellent suggestions. We are of the same architectural mind set. 1. Definitely. Coming from C# this is my background, but to keep the implementation and the idea of the architecture small enough to convey in less than 30 minutes I skipped this part. 2. For my app I have a lot of states. Idle, Busy, GeneralError, Offline, NoDataAvailable, WaitingForInput, ModalVisible that's all I can remember. I have a few apps where every view needs to react to the offline online state. Being in South Africa and making apps for the Africon continent sometimes you don't have the best connection so I grey out some things and show alternatives on others. USSD requests over networking etc. So the state's I've used is a great Idea. Remember that I frame this guide as a starting point since literally no one is pointing any devs in a direction with a clear guide and actual architecture and logic separation. Yes the provider builds the whole page ONLY WHEN MY STATE UPDATES. When your UI is in a widget it won't rebuild again (iirokrankka.com/2018/12/11/splitting-widgets-to-methods-performance-antipattern/), which is why I make it clear that if anything on your pages requires it's own logic and state changes you give it it's own model so that the main view doesn't rebuild for small UI changes. For instance all my network sensitive ui elements rebuild on their own based on a networkState stream so the main view never rebuilds when those small items change state. So the way you handle this is by sticking to the rules, only calling notifyListeners in your view when the state has changed. If your items will be static throughout the move it into it's own widget based on the article I linked above. Flutter will make the build more effecient if it's it's own widget with it's own context. You can test this as well. I might publish some performance stats using this but given that my views don't ever update often i doubt there's any performance draw backs. My buttons and any other major widgets with state changes are their own widgets with it's own model. I'll publish a follow up guide on how to expand at some point when I gather enough questions from community members. Yours will definitely be in there. Thank you for the feedback, I really appreciate it.
@@FilledStacks great! Yes, I also come from C# (Unity3D, Xamarin, WPF) and that's what I'm used to. I found that using just InheritedWidget and StreanandBuilder is a good middle ground, it's overkill for simple data and could be not enough for more complicated parts of the business logic, so, I divide it :) I've been trying Provider, I can make it work like a ViewModel for Xamarin and using the Providers as BindingContexts. The ViewModel would be provided to the pages Widgets as Inherited Widgets and works fine, just too much boilerplate code :/ I'm currently very busy, but I'm planning to create yet another state management package, very similar to Xamarin.Forms and by providing a ViewModel to your Widget and wrapping in a BindingContextWidget only what you want to rebuild and bind to the property you want in the VM, it will rebuild it when the property changes, just like it would do it in Forms, I believe it's a good approach, especially for those coming from Xamarin. I saw one guy did something very similar, but I can't see it scaling up to bigger apps. Same as provider, I can see too many providers for one page to avoid rebuilding widgets, while if you had one ViewModel per page and just notify the pieces that need rebuilding is much more efficient. Anyways, your tutorial is amazing and helped me understand provider better (I didn't want to figure it out on my own, it's easier to find a good TH-cam video like yours!)
@@nosmirck Awesome man. I don't quite see how provider doesn't scale for larger apps that have many places to rebuild it does perfectly well for me. Any widget that requires it's own logic or state changes will have it's own model and only rebuilds itself while all the other widgets keep their current state. Works perfectly for me in large apps, so I'm pretty happy with provider. I wouldn't complain about a notifyListeners that can take in a property name though. That would make things much easier to manage. Good luck on building that package, I look forward to using it.
Thank you, this video was very informative. I needed several hours to process all the info within... But I'm very confused as to why you decided to not inject the AuthenticationService for obtaining the User id in order to get the posts. you mention that "it does not make sense", but I don't really understand the reasoning. I have the following questions: 1) How do you decide when to use a Stream or when to inject a service? do you follow any particular rules? 2) What happens if you want/need to listen to multiple streams in your app? Do you surround your StreamProvider with another StreamProvider and so on for as many streams as you need? Does that even work?
Hey, you're welcome. I'm happy it helped. I used a stream specifically to show the example of providing the User as a stream to show the Provider functionality. I mention that in the video. I wouldn't do that in a real app, I would just use the service and get the current user like I do in my firebase custom user profiles video. Provider has something called a MultiProvider where you can supply as many providers as you want. I was simply showing off some provider functionality and the base for the architecture stacked, which I just released a video for.
@@FilledStacks Thank you. I already watched your Stacked architecture video, but I realized I was missing info so I backtracked and started doing this tutorial. I will finish watching the other Provider videos and I will make sure to check out your Firebase tutorials as well.
haha, That's awesome man! Happy to hear that you like it. I've wrapped all this functionality into a package called stacked with some additional functionality as well.
thank you for the amazing tutorial, i would like to ask you if you want to close stream controller where u will do that ?, unlike bloc pattern we were use dispose method for doing this ?
The provider does this for you automatically. For all the specialised providers, ChangeNotifierProvider, StreamProvider, ListenableProvider etc. If you're using the non-specific provider .i.e. Provider then there's an ondispose method where you can call model.dispose if you need to. The function calls back with your current data and you can call dispose on it.
I really learned a lot from this tutorial. I recently started learning flutter, and I am a bit confused about the naming conventions you follow or those that are followed in general. You really modularized your code into different files, can you please provide some tips on this?
I'm happy to hear that. Glad I could help. I don't know what tips you're expecting outside of what's in the videos? I base all of this on the SOLID principles so you can read and practice those then you should end up at a similar position as this architecture.
Awesome tutorial!! A little hard to follow because the speed of the explanation, but it was valuable anyways. I would like to learn how to prevent the user to go to login route when already logged in, and learn more about the locator technique used in this app tutorial.
Thank you. The speed is intentional. I needed to get a lot of information across in under 20 minutes. That's the reason I provide the complete written tutorial as well. All the code can be taken from there if you're following along to learn the concept of the architecture only. I'm happy to hear you got some value from it. The login route can be prevented outside of your Router. Just check if the user is logged in before you navigate there and don't navigate there.
Thank you for the informative video. Can you please explain how can we achieve the following scenario: Suppose we want to refresh the post from PostView screen. We may implement pull down to refresh in PostView screen and converting PostView widget into statefulWidget. This will allow us to reflect on the latest post. But how can we reflect this change on the HomeView screen which is still in the navigation stack?
Thanks for watching. Use a service to store the information you want and retrieve that information in any model you want to use. DON'T store it in the model, in either model where you want it. STORE IT IN A SERVICE. Have your posts in an information service and just expose it in the model through Post get post => service.getPost(index). You have the same problem as DuckyTheGoose in the comments, read the last reply there. And you can also check out the same problem here. github.com/FilledStacks/flutter-tutorials/issues/5
@@FilledStacks Thank you for the quick response. The Github issue states, not to use the same model twice because ChangeNotifierProvider will automatically dispose of when a view goes out of navigation scope. Having said that, the problem I stated is somewhat equivalent to notify the HomeModel when PostView screen is refreshed. I believe *STORE IT IN A SERVICE* means to implement it the way User is being implemented and referred in various views via Provider.of notation. That seems logical. :-) Another approach I could think of is to create a PostModel and pass it to the PostView via "onGenerateRoute" method. PostModel takes a Post and HomeModel(both can be passed as an argument object from HomeView) and then it updates the HomeModel whenever it changes. But it's a bit of an overkill and I am not sure how would it scale!
I can see how people get confused with using this. It's the fourth question about it so I'll make a video on it :) The video for this week is already done so I'll make the video for next week where I'll show how I would do it. And offer additional ways of doing it if they work when I try it out. Thanks for the feedback, it helps me figure out ideas for the next videos. I appreciate it.
Great video, I have learned a lot from you. a question: with this architecture how do you update the state of two different widgets on the same screen, when widget A makes the api call and the received data is saved in a singleton service, widget B receives that data from its viewModel accessing that service, widget B will display the data when some reaction happens that updates the UI.
I show that in part 2 of the new architecture series and in part 2 of this series you're watching now. You do the fetch in a service class which you then inject and access in both viewmodels that need that data.
Hey FilledStacks, after I watched this tutorial I noticed you didn't use any try catch for http request. How am I supposed to use try catch with this architecture, because if I put it inside LoginModel or AuthenticationService, there is no way to return the catched error message because the return value is type bool and If I put try catch in FlatButton onPressed, I can't call setState to change the ViewState to ViewState.Idle because it is outside BaseModel. Need your guidance
You add the try catch where you make the call. This tutorial isn't covering error handling or anything like that. I'd add it to the api service like in part 1 of my firebase auth series where I return the error message if there's an exception then show a dialog from the viewmodel.
Yes! That's where I come from, which is probably why :D C#, .net , .netcore and Xamarin before flutter. If you're using this architecture use the stacked package. All this code is wrapped in there.
I am learning flutter for last few months. This video and linked article really helped me come up with a application architecture. Thanks for your efforts!! There is one thing I don't understand that how to update only the state of one dependent widget which depends on a value that come from another widget. Calling setState(ViewState.Busy) will rebuild all the widgets under build method. Before using this approach, I have done this using Selector. How we are going to handle this in a Stateless widget ? Thanks
Hey, You should probably use the selector in the same way as you did for that functionality. I haven't used the selector so I cant give you a solution, but I do know that it's definitely part of the solution.
The view is wrapped in Consumer( ), this means every time when a small part of the model changes, the whole view is rebuild, this may be a performance issue. Provider package has Select( ) for this, but how can we make use of Select( ) in this proposed architecture?
Flutter is built to ensure that rebuilds are not expensive. We've had no problem with this, we use it specifically for the use in large high demand applications, but it's also easy for smaller apps. To use select you can simply call select I think. I've never looked into that functionality as we've never needed it. I only change code if it's required. I don't pre-optimize. Stacked has been working extremely well in all cases. Also keep in mind I'm using Mvvm here. when the viewmodel changes the view has to rebuild. Same think in redux. If you want a widget with its own viewmodel so onlt it rebuilds then that's also fine.
I've found that things can get messy (or imperative-feeling) checking the ViewState in the build methods, then building one widget or another. Is there a way to simplify this?
I usually break any grouped pieces of UI into it's own widget (with it's own model if it has logic). This way my UI stays compact on a view level. The reason I do states is because I use that to tell me which widgets to show, then those widgets all handle themselves with their own models logic. If you find that the view UI (which you should look at as the highest level) is too messy then you should group together pieces and create stateless widgets with it. View UI on my side has no detailed implementations in it. It's usually a column with a PostHeader, PostBody, CommentSection for dataAvailable state. and AppBusyLayout when Busy, etc. Then in those widgets I handle the logic. So the view always reads as a high level doc almost.
You also don't have to use the states. You can simply just deduce your UI based on values in your model. So if your posts is null you show loading, if it has a value but lenght 0, you show a message, otherwise you show the posts list. So the viewstates is for me to have nice and readable code, but it is very verbose. You can engineer a WidgetProvider that takes in a state and spits out a widget that takes in your model. This way you register all your widgets per state per view then just have a single WidgetProvider.getWidgetForState(state) call in your builder.
Thanks for the tutorial. I have a quick question. I'm using Firebase on the backend and I'm wondering what is the difference between the way you set up the StreamProvider in main with a controller and doing something like: StreamProvider.value(value: (AuthenticationService().getUser)) where getUser is a function in AuthenticationService that is: return _authentication.onAuthStateChanged(user)), where _authentication is a FirebaseAuth instance. Let me know if I can clarify.
You're welcome :) I think the only difference there is that it's a firebase auth object and not your own defined object so all your code using it will be dependent on the firebase library.
14:56 sorry, can you please elaborate on why injecting authentication service on home viewmodel doesn't make any sense? on what case it will become acceptable? what if it was posts viewmodel? thanks
"it makes no sense if you read the code" . You left that part out. Why would the home viewmodel need the authentication service if it's not performing any authentication functionality? Long term maintenance is heavily dependent on how easy the code is to read and be understood simply by reading. The question might come up "Why does the home viewmodel have the authentication service in it"
Using this architecture, Won't the whole view be rebuilt by calling setState inside the viewmodel? Or I should just wrap the BaseView on specific widgets that need to be rebuilt? If that's the case, multiple dynamic widgets (button, profile description row etc.) will be wrapped with the same viewmodel.
This whole view will be rebuilt, you just have the option of when to do that. I give widgets viewmodels if they can stand on their own logic so that only that widget rebuilds. Like the post list in the following video or a button with an internal loading indicator. Only the view with the builder will rebuild. This is not a problem, flutter rebuilds hundreds of times, when you open the keyboard, when you navigate, when you refresh, it's very optimised so it's no a problem.
I am using this architecture on one of our project. However I am a little bit stuck. I am rendering a view with LocationViewModel. However I need some information from my OrderViewModel to be render in that View. How can I go about this, since my viewModel must not know about each other.
Hey, if you watch my latest videos on stacked you'll see how it's handled. You move the data you want into a service, make it a reactive service and then let both viewmodels listen to it.
I have a HomeView and HomeModel. How do I provide the same homemodel to the searchdelegate class which I am showing after tapping on search action using the showSearch method?
A viewmodel is made specifically to manage the state of a single view. I've rarely shared a viewmodel. Usuall when it's the exact same logic with a different UI do I do it. something like different profile view throughout the app. If you want to supply the model to the search view then construct it and supply it like you do with the home view
@@FilledStacks The problem is how to provide it to the searchdelegate class as it's not a widget. One workaround is to supply the model to the whole material app and then access it inside searchdelegate class using Provider.of(context). Bu t I dont want to supply it to the whole material app.
@@mokshmahajan6340 I see. You wouldn't have to do that, I would go through callbacks or simply use a stateful widget and construct my model in the initState and keep a reference to it in the state locally to pass to the delegate.
Hi there! You passed the Post in the UI from one view to another. If your Post View needed some functionality, how would you pass the Post object to the view-model for that post?
@@FilledStacks So right now I am passing the Post object from one view to another using the Navigator (just like in the tutorial). To initiate the viewmodel, I access the object in the build func of the view (because we need context) and then from there I pass it to the locator when I add the ChangeNotifierProvider widget. Is that what you mean?
@@saadamin1156 No that's not what I mean. In the viewmodel builder where the ViewModel is being constructed you simply pass in the data you want. I think in this version of stacked we were still writing everything ourselves and getting the ViewModel from the locator. Uuuhhm, what you would have to do is construct your ViewModel in the model builder and pass in the data you want there. Like in this line github.com/FilledStacks/stacked-example/blob/8bbdbe7c19ebfe74028498022f834ea0596e782e/lib/ui/views/future_example/future_example_view.dart#L29 You'd simply pass any arguments you want. This uses stacked, which is the package I made using the videos you're watching now so that you don't have to continuously write the same code over and over in new projects.
@@FilledStacks Thanks a lot man! I am currently refactoring my app and I aim to explore your library inside out to get a better understanding of how it works. Beautiful architecture you have here.
@@saadamin1156 Thanks man. If you like this you will really like the stacked architecture. It's the package build from this setup. Some name changes but everything else is the same. In addition to the package which you can chech out here ( pub.dev/packages/stacked ) I have a full series dedicated to using stacked as your state management. th-cam.com/play/PLdTodMosi-BwM4XkagNwe4KADOMWQS5X-.html ... It goes over everything required to build an app using it.
Provider can be used with BLoC. It's mainly a full dependency injection library that helps you life your state up and provide it wherever possible. If you us bloc to manage your business logic then you use provider to provide your blocs to your views. So they're not mutually exclusive. They work together, the example om the provider page is how to inject your bloc using provider.
I've personally never like Bloc. For any app I've built. It's not intuitive, once you understand it then it is. But if you're trying to do normal stuff in Bloc and you're just starting out then it's counter intuitive at most times. And I've heard this from many developers.
Hi! Thanks for the nice tutorial. I am running 002-final. And when I enter userId for the first time and click login, the HomeView does not contain any posts, because fetching of posts occurs for the user provided by User.initial() with id=0. This only happens for the first login after starting the application. How to solve this problem?
Hello FilledStacks. Thank You for creating this beautiful content. :) Would you mind answering my question. I have a scenario. let's say I have a bottomNavigationBar in my app where the first-indexed widgets is with TabBar views (3 tabs) each containing listview and the second-index widget another TabBarView widgets resp. Basically BottomNavigationBar having two TabBarView widgets on index 1 and 2 resp. My problem is I have a favourite button in each listview of the 1st indexed widgets. Clicking on them I want to refresh the listviews with these item in the 2nd indexed widgets. I am having problem in it, because using notify listeners works only when i changes the tab inside the 2nd indexed widgets, but not while I change between the BottomNavigationBar widget. Is there any way to refresh the list with favorited item in the TabBarView lists. Currently I am using Post addPostFrameCallback as the user goes to 2nd index in bottomNavigationBar and using setState at the builder method.
hey there, use a service like in the second video with the PostService. Put a stream on your service, whenever you update the data add a value to the stream. a boolean or anything. subscribe to that stream in every viewmodel that you want to react ro the new data and call notifyListeners in the function.
Hey there! Awesome video as always. However, I got a couple of questions while playing with the architecture: 1. If the information needed for the initialization process of a model relies on different services, would be acceptable to unify all the calls to those services in one single function (e.g initModel() ) which should be called from the onModelready() callback? The view state should only be modified when all the calls to the services are completed, right? 2. If only some specific parts of the UI in a view depend on the state of the model, which approach would be better: making the whole view dependant on the model and conditionally render some ProgressIndicator here and there, or, in the other hand, considering the whole view a standard StatelessWidget and inserting where necessary a BaseView widget. Thanks for your time Dane!
1. No, the calls in onModelReady should be able to modify and update the state. for me atleast. think of having two calls. fetching some data (updating the state to show busy) then showing that data (updating state) and showing a dialog of some sorts if it's the first time on the view. all that logic can go in there as single calls to services.
2. I do both depending on the size of the widget. if it's something like the Posts widget I'd rather split it out into its own widget and model. if its something small like an error message or a indicator of sorts i would make the whole view stateless and render conditional widgets.
Hello FilledStacks.. first of all i wanna thank you for the amazing tutorial, it was very informative. I would like to ask you if you can make an example of an app using firestore with a bit of a complex data structure.. just like a social media app, where you can retrieve data of users you're following.. the fact that there aren't tutorials out there about this subject gives you a huge advantage and it would help us (me specifically) understand how to get specific data with as low reads as possible (for the sake of performance and pricing). I think provider and rxdart can help alot when it comes to these kind of complex projects but still there isn't a clear idea how. Thank you so much again and i hope that you consider making something soon if you can. Best regard.
Thank you for your kind words Joubagh. I have made a video where I show the use of Firebase as a service with this same architecture. th-cam.com/video/qa6A2TOqY0A/w-d-xo.html , the complex data infact doesn't change how the architecture will work. You still wrap it in a service, expose a stream and then consume that in your model. The video of me building gives a very clear path on how to link a set of firebase stream results to your model so it updates in real time. There's a part 2 as well th-cam.com/video/g5-ZkfN2mvY/w-d-xo.html which shows how I connect my query results to the model in real time. Then based on your data modeling for complex firestore documents I highly recommend Jeff from Fireship's videos. This one for data modeling: th-cam.com/video/35RlydUf6xo/w-d-xo.html His new provider video that shows how to use firebase data. You can still use my architecture and apply his techniques: th-cam.com/video/vFxk_KJCqgk/w-d-xo.html I hope this helps. If I do something as big as you ask, because there's a to cover in something like that it would be a course. And I don't know how willing people are to pay for a course from me yet. I'll definitely consider making a series, but the firebase+flutter app videos where I show how to integrate them has been the worst performing 😅so it's a hard sell to me right now. BUT, I will definitely post a series of snippets on it over on www.filledstacks.com/snippets , follow me on instagram @filledstacks, or twitter if you want to updates daily.
@@FilledStacks First thanks for your reply.. So, i don't think you understood what i meant or tried to explain to you.. you have a list of users you're following and there are alot of posts from all of the users.. what i want is to get a list of posts of users you're following only. You can do it by retrieving the list of users you're following and then for() each user you get their posts.. but still, i don't think it is the best approach when it comes to performance nor the amount of reads(cost of money). I still believe there's a better approach.. sub-collections can be an option but they mean there will be more writes (which is even more expensive but high performant). I hope i made it clearer.. just think of a social media app (get followings posts) and how to structre/retrieve data for it. Thanks again.
@@joubaghloubagh2917 Aaah, I see what you mean. I'm not as experienced in Firestore, I use all the resources from the fireship channel to do what I want. But from what I know you would have to duplicate the data (which is normal in noSQL land). I would not be able to give you a clear explanation. Did you watch the data modeling video on fireship? There's also this video th-cam.com/video/Lb-Pnytoi-8/w-d-xo.html where he explains how to keep your bill down in general. This might give you some pointers in the direction you want to go to keep that bill down.
@@joubaghloubagh2917 I hope it helps. Sorry I couldn't be of more help, as I gain experience in it I'll make more videos on Firestore but I'm very new to it at the moment. Starting a new project soon, so in a few months I'll be ready to make detailed videos on it. Might be to late then but I'll still put it out.
@@FilledStacks Like i mentioned before, duplicating data in this case means writing the same post for all users following (imaging thousands) and that can be expensive.
Hi, any advice for using Provider with View Models that contain other View Models? Couple of examples: 1. Form with n+ input fields, with validation, and a submit button that is only enabled when all input fields are valid 2. List of items where each item is a view model (maybe they can be in expanded/unexpanded state). I've tried this and its been very cumbersome. In case 1 I had a separate vm that has contained input data, validation state and validation rules. My goal was not to make the entire form rebuild when I the submit button changed state. To meed the goal I had to make the main vm listen to changes on the field vm and in the listener I updated the submit button state. To keep the entire form from being updated I used a value listener on the submit button and did not derive main vm from ChangeNotifier. In the package issues section there was a question similar to the above and the package author did not think it was a typical use case( my interpretation) and author suggested using multi/proxy providers to create the field vm separate and add get/set to main vm to add field vm to it. Cant say I'm to fond of that suggestion. Thanx for any help JA
Hi Jay, I don't have mucb advice on that. none of my viewmodels contain other viewmodels. I work through services to share data or produce states shsred across multiple viewmodels. I can't give any solid advice right now, it's quite a lot of questions. I usually only comment or give advice on solutions I've personally used in production. I'm planning a full architecture series and I'll definitely keep your comment in mind. Thank you very much for taking the time to type it out in such detail. I'm on my phone right now so I can't type a detailed response. I don't ever use vm's in other vm's I've never had to and I have the same functionality you're mentioning here. I'll look at the implementation some time and see if I can give you pointers based on what I did on my side.
Hi! How can i check if page mounted inside the model? I need this because when page is loaded i have async function inside the model which calls notifyListeners when ended but can cause an error when page is already disposed.
I don't know about mounting but the onModelReady call I setup in the BaseWidget is the call i use to run code when the view is created. Call you function on your model, when it's done call notifyListeners as the last call.
Version three of provider requires a stream instead of the controller. Change your property on the service to return the stream instead of the controller.
@@FilledStacks Thank you for awesome tutorial... but as you said for version 3 provider package we must use Stream instead of StreamProvider. I got confused how to adopt this in authentication_service.dart file
can i ask you why you dont use multiprovider for all the locator services . and you are you using consumer instead from a single initiation and thank you for this amazon tutorial
Hi there. I explain why I don't use provider only for injection. If I had multiple streams that I wanted to consume in the UI I would use multiprovider. I used stream because I only had one stream in this example. I'm using consumer as a base because I can then control what state to show based on the models state, then each widget that uses the base view can determine their own state. The view only updates once or twice, every widget in the view will have it's own model if it needs to update. This way the view doesn't re-render for small changes.
I was just wondering are you from South Africa? I mean your accent is so new to me :) ... nice content please keep the good work thanks a lot. Wish you all the best!!!
Hey, ProxyProvider doesn't produce very understandable code. If I struggle to understand a 6 service injection with everything around it then I'm sure new devs starting on a code base will too. Get_it is much cleaner. I aim for a maintainable code base, I don't mind having multiple packages that do the same thing.
@@danvilela I wouldn't have the awesome ChangeNotifierProvider to create my View-ViewModel binding. Well I would have it but I would simply build provider and then use that. I might remove it after a while since it's only the one part of Provider that I really need.
Hey. Thanks for this tutorial. I have one question in mind. How to structure the provider if i have multiple consumers scattered down the widget tree? cant use the base view since it places the consumer right below it. Should i just go the normal way of placing the provider on the nearest common widget? thanks.
Each widget can have it's own viewmodel just like in part 2 of this video where we build a comments widget. Each widget can have it's own viewmodel, so however you need you can make and bind per view using the change notifier provider. I currently use the provider_architecture which is the code for the BaseView with some more additions to take into account responsive layouts etc. You can check the latest State & API video for a walk through of how to use that library.
@@FilledStacks hey again. I have been playing around with the package for the last day and faced an issue. Is it possible to trigger the rebuild of a model from another model? i have two models in the same screen and i want a way for them to trigger each other. Thanks again for your amazing work.
@@ibrahimalazzawi2949 I use a service with a stream that I can subscribe too. I put a value on that stream when I want to update other models. You can also use a callback function on the service and register it in the model you want to update. You could also use the message hub to send out an update message for all viewmodels to update when the message is sent.
Thank you so much for creating these amazing tutorials. I'm new to flutter, I'm trying to implement your "Navigating without context" tutorial into this "Provider Architecture" Login and Posts example. I'm having issue when I'm trying to replace "Navigator.pushNamed(context, '/post', argument: posts[index]);" because this is inside a method "getPostsUi" and I don't have access to the "model". I have crated a function in home_model: void goToScreen(dynamic argument){ _navigationService.navigatTo(routes.PostRoute, arguments: argument); } Please let me know if function is right and how to get access to "model" in Widget methods if I don't want to pass it as a argument to widget method.
Thanks for the feedback man. I'm happy that it helped you. The models are all provided with Provider so you can do Provider.of(context) to get access to it.
Hi @Dani , I was reading the written tutorial and confused by the word called "reducing the state using data" "Models will ONLY request data from Services and reduce state from that DATA. Nothing else". I am not clear what is reducing state is?
To reduce something means to use the current state of an object to produce a state desirable for what you want to achieve. in this case we use the state of the service to reduce the values and state required to properly show the vie that is bound to the viewmodel.
@@FilledStacks what if I have a variable inside LocationService called currentLocation, and I use a ViewModel (exp. GoogleMapModel) to update the curentLocation value? I am doing this because the LocationService variable is shared between 2 views. Am I doing it the right way according to your guidelines?
@@alvin3171997 I can't see it exactly but I usually make the properties get only and update through functions on the service to accomodate logging potential.
Thank you, but the starting files on the repository are not the same files you started with in the tutorials. For instance, the viewmodel folder and the locator file are not included in the starting files in the repo.
Hey, dude, you did a great series describing architecture. just one thing that I don't understand how did you know when to register as factory, singleton, lazy singleton? and in case of using firebase service when you register as factory you didn't dispose the firebase call while you said when you register as a factory when there is dispose. the final point in my case I register firebase service as a lazy singleton and my model as factory I sometimes get a bad error this stream has read before.
Hey man, thanks. You register a singleton when you only want one instance of a class around, a factory if you want a new instance everytime the type is requested. You have to dispose your stream subscription in the models dispose or you can creat a broadcast stream but you might end up with multiple subscriptions.
Hey you don't NEED to. I prefer to do it because i write less code and the code is prone to change when i update dependent services in A provider. In short it's easier, for me, to maintain.
registerLazySingleton is the same as registerSingleton except that it only creates the instance when it's first requested. RegisterFactory registers the type and a new instance is returned everytime it's requested. Read my dependency injection article where I give a short description of the three. www.filledstacks.com/snippet/dependency-injection-in-flutter
I don't have it setup like that. In the future I might, but for now you can't. I'll make a zipped version available of each repo from now on to download from the website.
how to avoid unnecessary rebuilds? example: Widget A. Widget B. Widget C. Here when I update a state in Widget A with provider, the Widgets B and C rebuilds too. So how to avoid unnecessary rebuilds in B and C ?
Can you help me a bit? I have a home page with multiples carousels, and a want to build a widget for this carousels as they are all kind of the same (only need to change the title and they display the same kind of widget card) I need them to reach my webservice for pagination, how should I go about their state managment I mean the data source arrays, should I put each array and calls to the webservices at the home view model? I would really apreciate if you can help me to make this decision
Hey there. There's nothing special i would do. I'd have a model for the widget that manages the state. On construction I'd pass in the title and the url for the data to fetch. That's about it. The rest is ui code to build the widgets functionality
@@FilledStacks oh right I see. I added the arrays at the home view model, I call my api.dart there as well to update each array but I think your solution is way better as I wouldn't need to create a new array and method in the model for each carousel. Oh right man THANK YOU A LOT. I really think someone as kind as you is set to success thanks for replying all of our comments
@@AllenWillian That's a very nice comment man. I appreciate the honest feedback. Thank you for the well wishes, I really like teaching mobile app development. Let hope for some magnificent growth of the channel so that I can do a bit more to help out other devs.
I don't know what you're asking. if you want only sepcific users to see a post then you have to add visibility indicating values so that you can filter on the backend based on which user is requesting your data.
@@manishakushwaha1577 Then you should do that haha, what are you asking me? you put the statement above. Just use that to check if you should show the button or not.
Isn't it better when using Provider.of(context), with listen argument set to false: Provider.of(context, listen: false), to prevent it from unnecessarily rebuilding the widget. I am still learning, need clarification :) I read the documentation of Consumer at: pub.dev/documentation/provider/latest/provider/Consumer-class.html. There it says: "Unless listen: false is passed to Provider.of, the widget associated with the BuildContext passed to Provider.of will rebuild whenever the obtained value changes. This is the expected behavior, but sometimes it may rebuild more widgets than needed." I tried to set listen:false on your tutorial, and it works fine.
Yes, that's not fine. I won't say it's better. I'd say it'll not rebuild when that value changes. If that's what you want you should set it to false. Similarly to using a .nonReactive viewmodel builder in the latest tutorials. It's all dependent on what you want.
Hi filledstacks, thanks for such a great tutorial. I used to develop apps in react native where the architecture was well defined using redux for state management and redux persist for persisting state. I was wondering how we would persist state like lets say i want to persist user data and then on app start refresh it and send user directly to home screen.
Thank you :) You can use shared preferences. I have a short tutorial on it here www.filledstacks.com/snippet/custom-startup-logic-in-flutter/ . It uses shared preferences available on ios and android to write content to disk as string and allow you to read it up after. That tutorial covers exactly what you want to do. I hope that helps
Thanks a lot :) Do you follow the same file structure for bigger apps where there are a lot of statefull/stateless widgets in a single screen. How about grouping the widgets specific to a screen in one folder. Like Screens - screen1 - widgets - widget1 Widget1_view.dart widget1_model.dart - widget2 Widget2_view.dart screen1_view.dart screen1_model.dart -screen2 . . . In this way we can have all the widgets (both statefull and stateless) in a screen that may or may not need a model in one single folder of that screen. Widgets in the widget folder inside the screen folder will be screen specific widgets only. All common widgets will be in the shared folder.
@@vinitkadam_ Sounds good with me, I usually group it like that, sometimes I try something different. Widgets in their own folder, under UI. I'm still trying to figure it out as well so I'm trying different things for every project.
I really like this tutorial, and it looks like a great solution, but I have two questions: 1. How do you share data between views? I've always thought of state management as a solution to share data across your app, but this tutorial doesn't really cover that. Let's say you decide to add a user_profile view to this app. In that user profile, you want to show how many posts you have made. But the data is in your home_model, so how do you get to it without passing it through the navigator? 2. I see you give widgets their own viewmodel as well. If you decided to add business logic to the post_view, would you move the logic in comments_model to a new post_model? Or just keep it as a nested viewmodel? Thanks so much!
Hey there, it's pretty awesome. I've made v2 of this architecture it's part1 of the latest series Im posting. 1. To share data between viewmodels you make a service. I have a full video about that. 2. I'd keep it in the widgets model if that logic will be required for all instances of that viewmodel. If it's only required when it's in a certain context then I would move it one level up, out of the widgets viewmodel.
@@FilledStacks Thanks man. I noticed you reply to every single person here, that's awesome. Looking forward to watching your stacked videos. Subscribed!
@@hojdog You're welcome :) yes. I try my best to reply to every comment that I get. i think you'll like the stacked series if you like this video. Let me know what you think when you start watching it.
@@FilledStacks having been through your latest videos, I find it too complex as a beginner. There are so many dependencies to get everything working, just for the sake of keeping the logic separate from the presentation code. I don't think keeping the logic in the widget class is really an anti-pattern given that the presentation logic is in a separate build method already. I think i'd like to revisit your architecture when I have a bit more experience.
@@hojdog yes, I think that's the right move on your side. See how a code base feels and works over a year or two when you have the logic mixed with your UI then you make that decision. But your observation is correct, i literally do everything I can to keep the uI and the business logic separate so that I can unit test all my business logic and swap out UI's without being concerned about any logic. It also works very well in teams. If you don't see the benefit of it you definitely shouldn't be using it. I use it because we build 6-9 apps a year, other teams has to inherit the code when we're done with the base setup so having an architecture in place with clear guide lines will make it so that when they inherit a very large application they know exacly where to go to change something and know if it has dependencies on anything because it'll be clear from the viewmodel and service separation.
Hi, I need your help, I want to show "statusCode" and "reasonPhrase" on the top of the PostList UI(home_view) but I don't know how I can pass that from api >> getPostsForUser(int userId) method with the List. Future getPostsForUser(int userId) async { var posts = List(); // Get user posts for id var response = await client.get('$endpoint/posts?userId=$userId'); int statusCode = response.statusCode; String message = response.reasonPhrase; var parsed = json.decode(response.body) as List; // loop and convert each item to Post for (var post in parsed) { posts.add(Post.fromJson(post)); } return posts; }
That should be a separate request that gets that information separate from the posts request. If it's all in one request then update your serialisation to a model that contains the list of posts and the reason and status code in it and return that to your viewmodel
@@FilledStacks Thanks for quick reply. I was also planning the same thing. Now I'm more confident. I was also thinking that using FutureBuilder + Provider is not good approach as we are already doing setState and logic in viewmodel. Please let me know if I'm on right path. If not then, in which use case it's good to user FutureBuilder with this provider architecture.
@@yogeshbhati1359 Hi Yogi, I don't use anything else to manage state besides the View->ViewModel binding. The new Stacked package has a FutureViewModel and a StreamViewModel which basically does what Stream and Future builder does but for the Viewmodel. That's what I use now.
Very happy you love the tutorials. I do explain in the most simple details if you understand programming and object oriented principles. If you're a beginner in programming then these videos are not meant for you :) I don't intend on explaining the basics of programming at all. But there are a lot of good youtubers out there that cover the basics of object oriented programming
Great tutorial brother, just one thing can you please make a short video in which you can show us using flow chart how "provider + get it" exactly works it'll be a lot easier to under how these things work in a widget tree. Thanks
Thanks :) I don't think I'll be able to do that. Look up InheritedWidget in Flutter to understand how provider works and for get_it. You're simply storing references to an object (singleton) or references to a function that constructs an instance of an object. It's a short implementation. Basically a Map and you store the instances in there that you want to access later.
@@yashinherenttech6396 No not instances of provider. Instances of the types you want to retrieve later, or the functions that create the types you want to retrieve later.
hello cordial greeting, thanks for the tutorial, in reality it has served me a lot. but I have a problem when I use Navigator.pushReplacementNamed () to avoid the return to the previous screen, when I signout and return to the login and vicebersa, I get the following error: A HomeModel was used after being dispose. Once you have called dispose () on a HomeModel, it can no longer be a user. I appreciate your help
@@FilledStacks sorry dude I also register my model as a factory and i got the same error when i navigate to second page and when I am back to first page then try to go to second page again i got this error
I am getting this error [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: FormatException: Unexpected character (at character 1) please help me out from this error
Awesome tutorial. I'm having an issue with home_model. The List posts is null even if we call model.getPosts. I printed the list inside the function and I'm getting the values but posts is not getting the update.
Nevermind. I found the issue. I have a different question. Why do you use locator().userController on the StreamProvider instead of locator().userController.stream? The StreamProvider states that we need a Stream, not a StreamController.
When you can solve things after asking a question is the best. I do that on Stackoverflow sometimes. I'll post the question after hours of trying, 5 minutes after the question is up I figure it out then answer my own question haha
Hi, first good job on this tutorial I really liked it and it helped me a lot, second, I used the architecture as in your tutorial and I have a question about the user provider, I need to change his attributes sometimes and my question is where to handle this in the model or the view?
Hi, thank you. Any business logic or state management should be done in the model. The view should only pass data to the model that the user enters. No logic in the view, everything in the model.
@@danielrachlin9226 No the context should never be available in the model. the model only has business logic, it can't have anything related to the UI. Have a function on the model model.updateUser(String username). In that function you'll use the user service to update your user. userService.updateUserName(username) Then in the service you'll do the update to your current user. When you're done you'll call notifyListeners to update your model if needed.
If you register a type as a Factory you'll get a new instance back every time you request the type. If you register as a singleton you'll get the same instance back every time. More details description here under the setup. www.filledstacks.com/snippet/dependency-injection-in-flutter
Try changing the type of the left hand side, or casting the right hand side to 'Stream'. builder: (context) => locator().userController , why this error ??
I don't think there's enough content to cover a full video but I might do a short one. It's just a normal dependency injection container. You don't need it, but it's easier to use then inherited widget. There's not much else to say besides it's better than inherited widget to me because I don't have to make sure a widget is wrapped in an inherited. With this method you can get the object you need anywhere, even in other services that don't have the context for you to get your inherited widget from. I wrote a short post on how to set it up here. www.filledstacks.com/snippet/dependency-injection-in-flutter . Read up on Dependency Injection as a whole, then you'll see why I use it.
@@FilledStacks Thanks bro. Can you have a look at this issue : stackoverflow.com/questions/56191354/flutter-transition-new-page-reveals-below-old-page-elevated I could not get a solution to this. Please help if you can.
Hi man. Seems like you're just having a transition issue it's hard to imagine a transition based on words so you'll just have to play around with it or maybe someone has made the same thing already. Like this pub.dev/packages/page_transition
I was missing the setupLocator function in the main function and was getting the error of "Invalid argument (Object of type RegisterModel is not registered inside GetIt." I think this error is misguiding us. Either mention in the get_it package documentation, while registering the Model class or mention it as a second step that Model class must include SetupLocator in the main. github.com/fluttercommunity/get_it/issues/37
setupLocator has nothing to do with get_it. That's just what I call the function where I collect all the service registrations. The readme does mention you have to register a type before you can request it. That's how I knew to call setupLocator before the runApp call
Thanks! much appreciated. You would never need multiple models. A model is a one-to-one relation ship with its UI part. If you want multiple widgets with models then just make a normal widget and give it it's own model and put it in the view. But the view will still have one model. Model just directs anything it wants to do to a service, so everything you want to share should be in your services. Your multiple API calls will be in your ApiService. You'll just call the functions from the model.
@@FilledStacks so what about when one view needs the state stored in the model of another view? Shouldn't it be possible to nest models within a view? Say for example I'm working on a multipage form and on the last page I need to collect all the state data of the previous pages into one big object and send to the server. Isn't that a perfect candidate for letting the last page gain access to the previous page's models?
No. As I show in part two of the tutorial, the second video, you create a service that collects your info and then you share that between the models. Models never have to be kept inside other models unless it's a dynamic list of models that need to be created. And even then there's other ways of doing that.
This exception shows up wehen ever I try to run the app The following _Exception was thrown building MyApp: I/flutter (12226): Exception: Object of type AuthenticationService is not registered inside GetIt
Not a programmer but tried to learn Flutter. On building my first app, should I immediately apply this architecture (provider) ? Is this concept for the beginners?
No, definitely not. Learn Flutter first, follow the docs. Build everything you need from there. Everything.Only when the code becomes messy and a problem do you introduce state management.
Hi @filledStacks i love ur architecture and i am currently using it and God bless you for it.....Can u consider to architect flutter_bloc since it include provider now.? thanks
Thanks man. I'm happy to hear you're liking it. I'm not a fan of BLoC so I won't be using it or showing anything about it. It's a bit too complicated and around the way for me personally I like the more straight forward approach to app development that I've set out. No extra boiler plate, no additional constraints, just requirements and services that perform them. That's a long way of saying I will not be considering making a video about bloc, resocoder and robert brunhage have some very good tutorials on it that you can check out 😊
Yes, I've moved all the base widgets into a package called stacked which you can use so you don't have to re-write the base widget. My new architecture tutorial goes over that.
This line is not working on modern Android studio setup in start directory: (If I comment this line, all seems ok) Compiler message: lib/locator.dart:3:23: Error: Getter not found: 'instance'. GetIt locator = GetIt.instance; ^^^^^^^^
I think now I already can repeat each word of this video one by one with eyes closed, a must seen video ;-) ... I'm wondering, when the video for Stacked (pub.dev/packages/stacked)? hehe, thank so much Dane, so inspiring!
haha That's awesome Daniel. Thanks for watching! I have just finished the base architecture with some written parts. The first video will come out on Sunday which will cover everything that was done in this video for the bases then I'll do an additional few episodes to go into every detail of the architecture and how to extend it for your own app.
there are errors in the code(package:provider_architecutre???), some of the code, as well as packages, are already outdated and do not work, it is completely unclear on code inserts which file is being edited and in which place(it is easily solved by line numbering and file name) this is terrible material for learning(text version)
That makes total sense. It's 2 years old, and this has all been wrapped up into a package called pub.dev/packages/stacked which we use for all our clients.
If you are getting a dispose exception register the HomeModel as a Factory in the locator and not a singleton.
Thank you sir.
@@omprakashtiwari5486 You're welcome kind sir
@@FilledStacks How do you decide whether to register a model as a Factory, a lazy singleton or a singleton?
@@bayobizzle If there will only ever be one that never gets disposed then a singleton. If not then a factory
Yes bug is fixed but wait, what is it ''HomeModel was used after being disposed of.'' How it was disposed of??? we never disposed of HomeModel. Please explain this, It is huge confusion
This is THE video for anyone who has tried to use Provider in Flutter and gotten stuck. Pure gold!!
Still love this comment :)
Righteous!!! Yeah, it's a mountain to get over but it's worth it!!
Awesome to hear
@@FilledStacks Thank you so much for this gold video :)
@@aminefarhat8382 It's my pleasure, thanks for watching. These principles applies to the new stacked package as well, the only diffrence is I built all the viewmodel code in there so you don't have to :)
Months ago, I watched this tutorial and had no clue what was going on even though I understood how to use provider. Now I understand every piece of code and reason behind it after gaining more experience in Dart & Flutter. In summary, this is not a beginners video, so don't get overwhelmed. Level up and rewatch in a few month or year or however long it takes for you and comeback. Good job FiiledStacks!
Amazing. That's exactly what I hope for.
WOW!
So I started to learn flutter 3 weeks ago and the last 2 days I was working on an App where I wanted to target exactly the same problem as you did (provider, state management). And its so funny because you built almost exact the same app structure as I did. Even our folder structure is similar and we call the stuff same. Really funny how coders have the same mindset.
Btw: You did not only taught people how to use provider and state management, you also taught us how to structure a large app and keep a nice architecture. THATS GOLD and SO useful.
Btw I usually never comment on videos but you really deserve it. Take my sub!
I really appreciate your comment and thank you for taking the time to write it. It means a lot to me that you get value out of this and that you're learning from it. Thank you for the subscription and the feedback. I really appreciate it 🙏
@@FilledStacks I was wondering about one thing though which confuses me. Let's say you have a number in ur post widget and you can increase it on-click. Now you wanna see it on the PostView page to, when you navigate there. How would you achieve that in this architecture? Im confused because you have a list of posts. When we call Proivder.of it doesnt expect a specific list item... so I dont know how to achieve this.
@@cloud15487 If your Post widget has logic in it then I would create a Model for it and increase the number in there. I would keep my app data in a service called information service that has a list of all the posts. When I update one I'll go that list, manipulate it and save it locally (i you want it saved) and then when navigating I will now instead pass the post index, then retrieve the post information from the information service (which always has the updated post) and then display the information using the data on the data.
@@FilledStacks I am trying to achieve this right now but im not able to :( is there any chance you can provide an example in your Github Repo? What I want to achieve is following:
- Add a state to the post_list_item (e.g. a number)
- Add a button on it
- Everytime I press the button, the number is being incremented in HomeView and PostView.
- Warning: It can be incremented from the HomeView AND from the PostView.
I managed to implement it "one-way". If I increment it from HomeView, it works. I can see the change in the PostView too. But if I increment it from PostView, I cant see it in HomeView. I need the "navigator.pop" event to refetch the data from HomeView or something similar. Thats the issue I'm having. :(
The problem is, that whenever I pop back from PostView to HomeView, it will not update my HomeView. Its only updating it in "onModelReady" which refreshes the model in "InitState". That is the main problem I have when I use this architecture. Im sure there is a nice way to solve this, but I've tried for a few hours and im not getting anywhere. Right now I have implemented a button in the HomeView with " onPressed: () {model.getPosts();}" to synchronize the changes made in PostView with HomeView. But this is a very ugly solution as u would agree probably. I'd appreciate any help...
Just what I was waiting for. I used to search for Provider on youtube and medium every day since the I/O presentation. Thank you. You are the best.
Much appreciated
Brilliant! I have read medium posts, watched youtube videos and one paid for tutorial and could not get my head around the concept. I read your article, watched your video and it all falls into place. Not just how it works but how it all fits together in the Flutter framework. Thank you very much.
You're very welcome John. I had the same problem when I started in flutter. That's the reason I started my channel. There were no clear guides to do anything in terms of architecture. Bloc didn't work for me so when I came up with this for a client app I figured I'd share it with the rest of the community.
Can't believe something like this is free🙏Thank you so much!
😊 Happy to help. Thanks for watchig and commenting.
So impressive. Just starting with Flutter but this is exactly what I have been looking for coming from messy code tutorials. Thank you!
thank you for the comment. And thank you for letting me know that it helped you. I appreciate it. Check out the latest stacked architecture videos, it's the newer version of this video that you're watching.
I can't stop viewing this video over and over again, never seen such systemically organized code.
haha thanks for watching. Over and over :) I appreciate it.
Thank you! You have an excellent presentation style, and you explain content in a thorough manner.
Thank you. I appreciate the feedback.
Can We agree that this architecture needs to be the number ONE recommended architecture on FlutterDev? @FilledStacks is using Provider (Recommended state management technique), so this architecture could be the Recommended way to structure our apps. No craziness, easy to follow, easy to implement, easy to maintain. How do we make this happen?
Haha I like the positivity and support for the architecture. I agree that it's probably the easiest way to get into any kind of architecture that would provide a solid base for all size applications. I think one way for use to get it published or recommended is for you to share it as much as possible. And I'm not fishing for views, I think the flutter devs are very active in the community so the more they see something the bigger they know the impact is. Remi was found in the community for provider, and the more it was seen the more they worked it into their apps and then finally adopted it. Bloc was the same way until they let go of that. So i think sharing the video, writing your own articles about the setup,improving it, expanding on it, sharing the flaws of it, etc. Until we have a solid solid solid architecture that we can all be proud of. I'm just laying the base but there's lots I still need to add to it and explain before it's "complete".
@@FilledStacks Nice. I'm working on different projects (3 of them to be shipped next year) and I'm using this architecture. I'll try to create content for the Latin American community using this architecture (Probably help you out by adding Spanish captions to this video).
I love flutter now because of you.. I think Google's developers need to learn something to you.. Thank-you so much
Thank you for the kind words 🥳
Great video! Keep up the awesome work 🔥
Thank you. I'll try my best
Legends!! Exactly what i've been searching for days.. Well done guys! please keep up the great posts :)
Coming from Mvvm in Xamarin this structure brings in alot of the architecture and best practices I've come to appreciate and value
Thank you for the great feedback. I'm a Xamarin developer myself coming from MvvmCross so this makes is heavily inspired by that :) I'm happy you could see the link.
FilledStacks that’s awesome 🤙 I’m also in the mvvmcross space, 4years already. But loving flutter, so much better in many ways compared to xamarin.
Hello Dane, first of all i've been watching your tutorials lately and i find them the best, thanks man!
I have a question, i used the same way you mentioned in this video to build my flutter APP that deals with an API i made, i face a problem that the first time i open the APP the user id entered is not taken in consideration, instead initial value is used (0), then going back to login and login again dose the magic. I suspect the StreamProvider dosen't supply User to homeview on the first time. I tried a lot, the values stuck on 0 as a first time. any thoughts please?
I think i figured it out :)
After some reading in the provider documentation i found out that create callback is lazy-loaded which means it's called the first time the value is read instead of the first time the provider is created, that was giving me first just the initial data (0 in our case).
The solution was just to set lazy to false inside the StreamProvider.
@@hasanimam82 thanks for commenting the solution as well. It helps the other devs that might be dealing with the same things. Thanks also for checking out the videos and typing up some feedback, I really appreciate it.
Excellent video, however, I have a few suggestions to make it better:
1) use interfaces for the services. It's needed when you start making tests, or even during development, sometimes we want a mocked service registered to work on something we want specifically to work with (let's say, edge cases).
2) for a viewstate you might need specific states per page, in this case I use an enum per page and a single boolean for "isBusy" doesn't change too much of what you did and gives the flexibility to add more than 2 stages. So, if isBusy is true, the view is busy, otherwise it is idle however, the page's state can be anything depending on your app's logic (in my case, I have an upload button that creates a state "uploading" which will add a small message, however, the page is not busy, I can still use the rest of it except for the upload button).
Now, a couple of questions'
Isn't the provider rebuilding the whole page? I mean, I don't need to rebuild the login title, but when it triggers the setState, isn't it rebuilding it? I know is not much, just one text, but image that this page has a lot more that I don't want to rebuild, how should I handle this?
Excellent suggestions. We are of the same architectural mind set.
1. Definitely. Coming from C# this is my background, but to keep the implementation and the idea of the architecture small enough to convey in less than 30 minutes I skipped this part.
2. For my app I have a lot of states. Idle, Busy, GeneralError, Offline, NoDataAvailable, WaitingForInput, ModalVisible that's all I can remember. I have a few apps where every view needs to react to the offline online state. Being in South Africa and making apps for the Africon continent sometimes you don't have the best connection so I grey out some things and show alternatives on others. USSD requests over networking etc. So the state's I've used is a great Idea. Remember that I frame this guide as a starting point since literally no one is pointing any devs in a direction with a clear guide and actual architecture and logic separation.
Yes the provider builds the whole page ONLY WHEN MY STATE UPDATES. When your UI is in a widget it won't rebuild again (iirokrankka.com/2018/12/11/splitting-widgets-to-methods-performance-antipattern/), which is why I make it clear that if anything on your pages requires it's own logic and state changes you give it it's own model so that the main view doesn't rebuild for small UI changes. For instance all my network sensitive ui elements rebuild on their own based on a networkState stream so the main view never rebuilds when those small items change state.
So the way you handle this is by sticking to the rules, only calling notifyListeners in your view when the state has changed. If your items will be static throughout the move it into it's own widget based on the article I linked above. Flutter will make the build more effecient if it's it's own widget with it's own context. You can test this as well. I might publish some performance stats using this but given that my views don't ever update often i doubt there's any performance draw backs. My buttons and any other major widgets with state changes are their own widgets with it's own model. I'll publish a follow up guide on how to expand at some point when I gather enough questions from community members. Yours will definitely be in there.
Thank you for the feedback, I really appreciate it.
@@FilledStacks great! Yes, I also come from C# (Unity3D, Xamarin, WPF) and that's what I'm used to.
I found that using just InheritedWidget and StreanandBuilder is a good middle ground, it's overkill for simple data and could be not enough for more complicated parts of the business logic, so, I divide it :)
I've been trying Provider, I can make it work like a ViewModel for Xamarin and using the Providers as BindingContexts. The ViewModel would be provided to the pages Widgets as Inherited Widgets and works fine, just too much boilerplate code :/
I'm currently very busy, but I'm planning to create yet another state management package, very similar to Xamarin.Forms and by providing a ViewModel to your Widget and wrapping in a BindingContextWidget only what you want to rebuild and bind to the property you want in the VM, it will rebuild it when the property changes, just like it would do it in Forms, I believe it's a good approach, especially for those coming from Xamarin.
I saw one guy did something very similar, but I can't see it scaling up to bigger apps. Same as provider, I can see too many providers for one page to avoid rebuilding widgets, while if you had one ViewModel per page and just notify the pieces that need rebuilding is much more efficient.
Anyways, your tutorial is amazing and helped me understand provider better (I didn't want to figure it out on my own, it's easier to find a good TH-cam video like yours!)
@@nosmirck Awesome man. I don't quite see how provider doesn't scale for larger apps that have many places to rebuild it does perfectly well for me. Any widget that requires it's own logic or state changes will have it's own model and only rebuilds itself while all the other widgets keep their current state. Works perfectly for me in large apps, so I'm pretty happy with provider. I wouldn't complain about a notifyListeners that can take in a property name though. That would make things much easier to manage. Good luck on building that package, I look forward to using it.
Best video of Provider by far on youtube
Awesome! The new architecture videos will be coming out soon
Thank you, this video was very informative. I needed several hours to process all the info within...
But I'm very confused as to why you decided to not inject the AuthenticationService for obtaining the User id in order to get the posts. you mention that "it does not make sense", but I don't really understand the reasoning. I have the following questions:
1) How do you decide when to use a Stream or when to inject a service? do you follow any particular rules?
2) What happens if you want/need to listen to multiple streams in your app? Do you surround your StreamProvider with another StreamProvider and so on for as many streams as you need? Does that even work?
Hey, you're welcome. I'm happy it helped. I used a stream specifically to show the example of providing the User as a stream to show the Provider functionality. I mention that in the video. I wouldn't do that in a real app, I would just use the service and get the current user like I do in my firebase custom user profiles video. Provider has something called a MultiProvider where you can supply as many providers as you want. I was simply showing off some provider functionality and the base for the architecture stacked, which I just released a video for.
@@FilledStacks Thank you. I already watched your Stacked architecture video, but I realized I was missing info so I backtracked and started doing this tutorial. I will finish watching the other Provider videos and I will make sure to check out your Firebase tutorials as well.
@@ziritrion Awesome! Happy to see you're doing the full rounds. I've finished the written for the latest tutorial I will record and release on Sunday.
Maaaannnnn....!!!!
That's too good...👌
I will change my entire app progress of last two weeks. After what I just watched.
haha, That's awesome man! Happy to hear that you like it. I've wrapped all this functionality into a package called stacked with some additional functionality as well.
A South African TH-camr!
Yup yup!!! :D
thank you for the amazing tutorial, i would like to ask you if you want to close stream controller where u will do that ?,
unlike bloc pattern we were use dispose method for doing this ?
The provider does this for you automatically. For all the specialised providers, ChangeNotifierProvider, StreamProvider, ListenableProvider etc. If you're using the non-specific provider .i.e. Provider then there's an ondispose method where you can call model.dispose if you need to. The function calls back with your current data and you can call dispose on it.
Searching examples of the flutter provider has arrived here.
Excellent video very well explained.
I will look forward to your next videos.
Thank you.
Thank you, I'm happy to hear that you found some value in it.
I really learned a lot from this tutorial. I recently started learning flutter, and I am a bit confused about the naming conventions you follow or those that are followed in general. You really modularized your code into different files, can you please provide some tips on this?
I'm happy to hear that. Glad I could help. I don't know what tips you're expecting outside of what's in the videos? I base all of this on the SOLID principles so you can read and practice those then you should end up at a similar position as this architecture.
Awesome tutorial!! A little hard to follow because the speed of the explanation, but it was valuable anyways. I would like to learn how to prevent the user to go to login route when already logged in, and learn more about the locator technique used in this app tutorial.
Thank you. The speed is intentional. I needed to get a lot of information across in under 20 minutes. That's the reason I provide the complete written tutorial as well. All the code can be taken from there if you're following along to learn the concept of the architecture only. I'm happy to hear you got some value from it. The login route can be prevented outside of your Router. Just check if the user is logged in before you navigate there and don't navigate there.
Thank you for the informative video.
Can you please explain how can we achieve the following scenario:
Suppose we want to refresh the post from PostView screen. We may implement pull down to refresh in PostView screen and converting PostView widget into statefulWidget. This will allow us to reflect on the latest post. But how can we reflect this change on the HomeView screen which is still in the navigation stack?
Thanks for watching. Use a service to store the information you want and retrieve that information in any model you want to use. DON'T store it in the model, in either model where you want it. STORE IT IN A SERVICE. Have your posts in an information service and just expose it in the model through Post get post => service.getPost(index). You have the same problem as DuckyTheGoose in the comments, read the last reply there. And you can also check out the same problem here. github.com/FilledStacks/flutter-tutorials/issues/5
@@FilledStacks Thank you for the quick response.
The Github issue states, not to use the same model twice because ChangeNotifierProvider will automatically dispose of when a view goes out of navigation scope.
Having said that, the problem I stated is somewhat equivalent to notify the HomeModel when PostView screen is refreshed. I believe *STORE IT IN A SERVICE* means to implement it the way User is being implemented and referred in various views via Provider.of notation. That seems logical. :-)
Another approach I could think of is to create a PostModel and pass it to the PostView via "onGenerateRoute" method. PostModel takes a Post and HomeModel(both can be passed as an argument object from HomeView) and then it updates the HomeModel whenever it changes. But it's a bit of an overkill and I am not sure how would it scale!
I can see how people get confused with using this. It's the fourth question about it so I'll make a video on it :) The video for this week is already done so I'll make the video for next week where I'll show how I would do it. And offer additional ways of doing it if they work when I try it out. Thanks for the feedback, it helps me figure out ideas for the next videos. I appreciate it.
this tutorial worth my subscription. thanks and you deserved it
Thank you for subscribing :) Happy to hear you're enjoying the content.
Great video, I have learned a lot from you. a question: with this architecture how do you update the state of two different widgets on the same screen, when widget A makes the api call and the received data is saved in a singleton service, widget B receives that data from its viewModel accessing that service, widget B will display the data when some reaction happens that updates the UI.
I show that in part 2 of the new architecture series and in part 2 of this series you're watching now. You do the fetch in a service class which you then inject and access in both viewmodels that need that data.
@@FilledStacks Great, Thanks
Hey FilledStacks, after I watched this tutorial I noticed you didn't use any try catch for http request. How am I supposed to use try catch with this architecture, because if I put it inside LoginModel or AuthenticationService, there is no way to return the catched error message because the return value is type bool and If I put try catch in FlatButton onPressed, I can't call setState to change the ViewState to ViewState.Idle because it is outside BaseModel. Need your guidance
You add the try catch where you make the call. This tutorial isn't covering error handling or anything like that. I'd add it to the api service like in part 1 of my firebase auth series where I return the error message if there's an exception then show a dialog from the viewmodel.
@@FilledStacks Okay I am going to watch the firebase auth video, thanks
How to use the automaticKeppAliveClientMixin in provider architecture? Or is there any way to preserve state in navigators?
Use a stateful widget like you would usually :)
This is similar to how I do things in wpf, it makes so much sense to do it like this
Yes! That's where I come from, which is probably why :D C#, .net , .netcore and Xamarin before flutter.
If you're using this architecture use the stacked package. All this code is wrapped in there.
I am learning flutter for last few months. This video and linked article really helped me come up with a application architecture. Thanks for your efforts!! There is one thing I don't understand that how to update only the state of one dependent widget which depends on a value that come from another widget. Calling setState(ViewState.Busy) will rebuild all the widgets under build method. Before using this approach, I have done this using Selector. How we are going to handle this in a Stateless widget ? Thanks
Hey, You should probably use the selector in the same way as you did for that functionality. I haven't used the selector so I cant give you a solution, but I do know that it's definitely part of the solution.
@@FilledStacks Thanks
The view is wrapped in Consumer( ), this means every time when a small part of the model changes, the whole view is rebuild, this may be a performance issue. Provider package has Select( ) for this, but how can we make use of Select( ) in this proposed architecture?
Flutter is built to ensure that rebuilds are not expensive. We've had no problem with this, we use it specifically for the use in large high demand applications, but it's also easy for smaller apps.
To use select you can simply call select I think. I've never looked into that functionality as we've never needed it. I only change code if it's required. I don't pre-optimize. Stacked has been working extremely well in all cases.
Also keep in mind I'm using Mvvm here. when the viewmodel changes the view has to rebuild. Same think in redux. If you want a widget with its own viewmodel so onlt it rebuilds then that's also fine.
I've found that things can get messy (or imperative-feeling) checking the ViewState in the build methods, then building one widget or another. Is there a way to simplify this?
I usually break any grouped pieces of UI into it's own widget (with it's own model if it has logic). This way my UI stays compact on a view level. The reason I do states is because I use that to tell me which widgets to show, then those widgets all handle themselves with their own models logic. If you find that the view UI (which you should look at as the highest level) is too messy then you should group together pieces and create stateless widgets with it. View UI on my side has no detailed implementations in it. It's usually a column with a PostHeader, PostBody, CommentSection for dataAvailable state. and AppBusyLayout when Busy, etc. Then in those widgets I handle the logic. So the view always reads as a high level doc almost.
You also don't have to use the states. You can simply just deduce your UI based on values in your model. So if your posts is null you show loading, if it has a value but lenght 0, you show a message, otherwise you show the posts list. So the viewstates is for me to have nice and readable code, but it is very verbose. You can engineer a WidgetProvider that takes in a state and spits out a widget that takes in your model. This way you register all your widgets per state per view then just have a single WidgetProvider.getWidgetForState(state) call in your builder.
what about if we have an authtoken that we can get it once the user is logged in and we want to pass it as a header to http post request.
Yup. I get minde directly from my authentication service when making http request in my api class
I am like 6 months old in flutter and all these are too good videos...kudos..Is there a follow-up video on this?
Yes. Everything written here has been wrapped into a package called Stacked and I show the latest flutter app setup using stacked.
Thanks for the tutorial. I have a quick question. I'm using Firebase on the backend and I'm wondering what is the difference between the way you set up the StreamProvider in main with a controller and doing something like:
StreamProvider.value(value: (AuthenticationService().getUser))
where getUser is a function in AuthenticationService that is:
return _authentication.onAuthStateChanged(user)), where _authentication is a FirebaseAuth instance. Let me know if I can clarify.
You're welcome :) I think the only difference there is that it's a firebase auth object and not your own defined object so all your code using it will be dependent on the firebase library.
14:56 sorry, can you please elaborate on why injecting authentication service on home viewmodel doesn't make any sense? on what case it will become acceptable? what if it was posts viewmodel? thanks
"it makes no sense if you read the code" . You left that part out. Why would the home viewmodel need the authentication service if it's not performing any authentication functionality?
Long term maintenance is heavily dependent on how easy the code is to read and be understood simply by reading. The question might come up "Why does the home viewmodel have the authentication service in it"
Using this architecture, Won't the whole view be rebuilt by calling setState inside the viewmodel?
Or I should just wrap the BaseView on specific widgets that need to be rebuilt?
If that's the case, multiple dynamic widgets (button, profile description row etc.) will be wrapped with the same viewmodel.
This whole view will be rebuilt, you just have the option of when to do that. I give widgets viewmodels if they can stand on their own logic so that only that widget rebuilds. Like the post list in the following video or a button with an internal loading indicator. Only the view with the builder will rebuild. This is not a problem, flutter rebuilds hundreds of times, when you open the keyboard, when you navigate, when you refresh, it's very optimised so it's no a problem.
I am using this architecture on one of our project. However I am a little bit stuck. I am rendering a view with LocationViewModel. However I need some information from my OrderViewModel to be render in that View. How can I go about this, since my viewModel must not know about each other.
Hey, if you watch my latest videos on stacked you'll see how it's handled. You move the data you want into a service, make it a reactive service and then let both viewmodels listen to it.
I have a HomeView and HomeModel. How do I provide the same homemodel to the searchdelegate class which I am showing after tapping on search action using the showSearch method?
A viewmodel is made specifically to manage the state of a single view. I've rarely shared a viewmodel. Usuall when it's the exact same logic with a different UI do I do it. something like different profile view throughout the app.
If you want to supply the model to the search view then construct it and supply it like you do with the home view
@@FilledStacks The problem is how to provide it to the searchdelegate class as it's not a widget. One workaround is to supply the model to the whole material app and then access it inside searchdelegate class using Provider.of(context). Bu t I dont want to supply it to the whole material app.
@@mokshmahajan6340 I see. You wouldn't have to do that, I would go through callbacks or simply use a stateful widget and construct my model in the initState and keep a reference to it in the state locally to pass to the delegate.
Hi there! You passed the Post in the UI from one view to another. If your Post View needed some functionality, how would you pass the Post object to the view-model for that post?
Hi hi, I would pass that to the viewmodel when it's being constructed in the ViewModel builder.
@@FilledStacks So right now I am passing the Post object from one view to another using the Navigator (just like in the tutorial). To initiate the viewmodel, I access the object in the build func of the view (because we need context) and then from there I pass it to the locator when I add the ChangeNotifierProvider widget.
Is that what you mean?
@@saadamin1156 No that's not what I mean. In the viewmodel builder where the ViewModel is being constructed you simply pass in the data you want. I think in this version of stacked we were still writing everything ourselves and getting the ViewModel from the locator. Uuuhhm, what you would have to do is construct your ViewModel in the model builder and pass in the data you want there. Like in this line github.com/FilledStacks/stacked-example/blob/8bbdbe7c19ebfe74028498022f834ea0596e782e/lib/ui/views/future_example/future_example_view.dart#L29 You'd simply pass any arguments you want.
This uses stacked, which is the package I made using the videos you're watching now so that you don't have to continuously write the same code over and over in new projects.
@@FilledStacks Thanks a lot man! I am currently refactoring my app and I aim to explore your library inside out to get a better understanding of how it works. Beautiful architecture you have here.
@@saadamin1156 Thanks man. If you like this you will really like the stacked architecture. It's the package build from this setup. Some name changes but everything else is the same. In addition to the package which you can chech out here ( pub.dev/packages/stacked ) I have a full series dedicated to using stacked as your state management. th-cam.com/play/PLdTodMosi-BwM4XkagNwe4KADOMWQS5X-.html ... It goes over everything required to build an app using it.
In your opinion, how is it compare to the Bloc one?
Provider can be used with BLoC. It's mainly a full dependency injection library that helps you life your state up and provide it wherever possible. If you us bloc to manage your business logic then you use provider to provide your blocs to your views. So they're not mutually exclusive. They work together, the example om the provider page is how to inject your bloc using provider.
I've personally never like Bloc. For any app I've built. It's not intuitive, once you understand it then it is. But if you're trying to do normal stuff in Bloc and you're just starting out then it's counter intuitive at most times. And I've heard this from many developers.
Hi! Thanks for the nice tutorial. I am running 002-final. And when I enter userId for the first time and click login, the HomeView does not contain any posts, because fetching of posts occurs for the user provided by User.initial() with id=0. This only happens for the first login after starting the application. How to solve this problem?
You have to set lazy to false for that provider. Lazy loading was added a few months after this video came out.
@@FilledStacks It's work! Thanks a lot!
@@sergeystorozhev6949 Great!
Hello FilledStacks. Thank You for creating this beautiful content. :)
Would you mind answering my question.
I have a scenario. let's say I have a bottomNavigationBar in my app where the first-indexed widgets is with TabBar views (3 tabs) each containing listview and the second-index widget another TabBarView widgets resp.
Basically BottomNavigationBar having two TabBarView widgets on index 1 and 2 resp.
My problem is I have a favourite button in each listview of the 1st indexed widgets. Clicking on them I want to refresh the listviews with these item in the 2nd indexed widgets. I am having problem in it, because using notify listeners works only when i changes the tab inside the 2nd indexed widgets, but not while I change between the BottomNavigationBar widget. Is there any way to refresh the list with favorited item in the TabBarView lists. Currently I am using Post addPostFrameCallback as the user goes to 2nd index in bottomNavigationBar and using setState at the builder method.
hey there, use a service like in the second video with the PostService. Put a stream on your service, whenever you update the data add a value to the stream. a boolean or anything. subscribe to that stream in every viewmodel that you want to react ro the new data and call notifyListeners in the function.
Hey there! Awesome video as always. However, I got a couple of questions while playing with the architecture:
1. If the information needed for the initialization process of a model relies on different services, would be acceptable to unify all the calls to those services in one single function (e.g initModel() ) which should be called from the onModelready() callback? The view state should only be modified when all the calls to the services are completed, right?
2. If only some specific parts of the UI in a view depend on the state of the model, which approach would be better: making the whole view dependant on the model and conditionally render some ProgressIndicator here and there, or, in the other hand, considering the whole view a standard StatelessWidget and inserting where necessary a BaseView widget.
Thanks for your time Dane!
1. No, the calls in onModelReady should be able to modify and update the state. for me atleast. think of having two calls. fetching some data (updating the state to show busy) then showing that data (updating state) and showing a dialog of some sorts if it's the first time on the view. all that logic can go in there as single calls to services.
2. I do both depending on the size of the widget. if it's something like the Posts widget I'd rather split it out into its own widget and model. if its something small like an error message or a indicator of sorts i would make the whole view stateless and render conditional widgets.
Hello FilledStacks.. first of all i wanna thank you for the amazing tutorial, it was very informative.
I would like to ask you if you can make an example of an app using firestore with a bit of a complex data structure.. just like a social media app, where you can retrieve data of users you're following.. the fact that there aren't tutorials out there about this subject gives you a huge advantage and it would help us (me specifically) understand how to get specific data with as low reads as possible (for the sake of performance and pricing). I think provider and rxdart can help alot when it comes to these kind of complex projects but still there isn't a clear idea how.
Thank you so much again and i hope that you consider making something soon if you can.
Best regard.
Thank you for your kind words Joubagh. I have made a video where I show the use of Firebase as a service with this same architecture. th-cam.com/video/qa6A2TOqY0A/w-d-xo.html , the complex data infact doesn't change how the architecture will work. You still wrap it in a service, expose a stream and then consume that in your model. The video of me building gives a very clear path on how to link a set of firebase stream results to your model so it updates in real time. There's a part 2 as well th-cam.com/video/g5-ZkfN2mvY/w-d-xo.html which shows how I connect my query results to the model in real time.
Then based on your data modeling for complex firestore documents I highly recommend Jeff from Fireship's videos. This one for data modeling: th-cam.com/video/35RlydUf6xo/w-d-xo.html
His new provider video that shows how to use firebase data. You can still use my architecture and apply his techniques: th-cam.com/video/vFxk_KJCqgk/w-d-xo.html
I hope this helps. If I do something as big as you ask, because there's a to cover in something like that it would be a course. And I don't know how willing people are to pay for a course from me yet. I'll definitely consider making a series, but the firebase+flutter app videos where I show how to integrate them has been the worst performing 😅so it's a hard sell to me right now. BUT, I will definitely post a series of snippets on it over on www.filledstacks.com/snippets , follow me on instagram @filledstacks, or twitter if you want to updates daily.
@@FilledStacks First thanks for your reply.. So, i don't think you understood what i meant or tried to explain to you..
you have a list of users you're following and there are alot of posts from all of the users.. what i want is to get a list of posts of users you're following only.
You can do it by retrieving the list of users you're following and then for() each user you get their posts.. but still, i don't think it is the best approach when it comes to performance nor the amount of reads(cost of money).
I still believe there's a better approach.. sub-collections can be an option but they mean there will be more writes (which is even more expensive but high performant).
I hope i made it clearer.. just think of a social media app (get followings posts) and how to structre/retrieve data for it.
Thanks again.
@@joubaghloubagh2917 Aaah, I see what you mean. I'm not as experienced in Firestore, I use all the resources from the fireship channel to do what I want. But from what I know you would have to duplicate the data (which is normal in noSQL land). I would not be able to give you a clear explanation. Did you watch the data modeling video on fireship? There's also this video th-cam.com/video/Lb-Pnytoi-8/w-d-xo.html where he explains how to keep your bill down in general. This might give you some pointers in the direction you want to go to keep that bill down.
@@joubaghloubagh2917 I hope it helps. Sorry I couldn't be of more help, as I gain experience in it I'll make more videos on Firestore but I'm very new to it at the moment. Starting a new project soon, so in a few months I'll be ready to make detailed videos on it. Might be to late then but I'll still put it out.
@@FilledStacks Like i mentioned before, duplicating data in this case means writing the same post for all users following (imaging thousands) and that can be expensive.
Hi, any advice for using Provider with View Models that contain other View Models? Couple of examples:
1. Form with n+ input fields, with validation, and a submit button that is only enabled when all input fields are valid
2. List of items where each item is a view model (maybe they can be in expanded/unexpanded state).
I've tried this and its been very cumbersome.
In case 1 I had a separate vm that has contained input data, validation state and validation rules. My goal was not to make the entire form rebuild when I the submit button changed state. To meed the goal I had to make the main vm listen to changes on the field vm and in the listener I updated the submit button state. To keep the entire form from being updated I used a value listener on the submit button and did not derive main vm from ChangeNotifier.
In the package issues section there was a question similar to the above and the package author did not think it was a typical use case( my interpretation) and author suggested using multi/proxy providers to create the field vm separate and add get/set to main vm to add field vm to it. Cant say I'm to fond of that suggestion.
Thanx for any help
JA
Hi Jay, I don't have mucb advice on that. none of my viewmodels contain other viewmodels. I work through services to share data or produce states shsred across multiple viewmodels.
I can't give any solid advice right now, it's quite a lot of questions. I usually only comment or give advice on solutions I've personally used in production.
I'm planning a full architecture series and I'll definitely keep your comment in mind. Thank you very much for taking the time to type it out in such detail. I'm on my phone right now so I can't type a detailed response.
I don't ever use vm's in other vm's I've never had to and I have the same functionality you're mentioning here. I'll look at the implementation some time and see if I can give you pointers based on what I did on my side.
Truly appreciate the quick response. I doubt what I typed made alot of sense. Hope u and yours are well in this crazy time.
Hi! How can i check if page mounted inside the model? I need this because when page is loaded i have async function inside the model which calls notifyListeners when ended but can cause an error when page is already disposed.
I don't know about mounting but the onModelReady call I setup in the BaseWidget is the call i use to run code when the view is created. Call you function on your model, when it's done call notifyListeners as the last call.
The return type 'StreamController' isn't a 'Stream', as defined by anonymous closure.
Version three of provider requires a stream instead of the controller. Change your property on the service to return the stream instead of the controller.
I had difficulty adopting this
@@bibash3128 What were you struggling with?
@@FilledStacks Thank you for awesome tutorial... but as you said for version 3 provider package we must use Stream instead of StreamProvider. I got confused how to adopt this in authentication_service.dart file
@@bibash3128 Oh I see. Instead of exposing the controller, expose controller.stream that's the only difference.
can i ask you why you dont use multiprovider for all the locator services . and you are you using consumer instead from a single initiation and thank you for this amazon tutorial
Hi there. I explain why I don't use provider only for injection. If I had multiple streams that I wanted to consume in the UI I would use multiprovider. I used stream because I only had one stream in this example. I'm using consumer as a base because I can then control what state to show based on the models state, then each widget that uses the base view can determine their own state. The view only updates once or twice, every widget in the view will have it's own model if it needs to update. This way the view doesn't re-render for small changes.
I was just wondering are you from South Africa? I mean your accent is so new to me :) ... nice content please keep the good work thanks a lot. Wish you all the best!!!
Hi Ahmed 👋. Yes I am 😁 nice ear. Thank you for the compliment and the well wishes. I appreciate it
Very cool architecture! But why use locator instead of Provider + ProxyProvider? Since you are already using the package?
Hey, ProxyProvider doesn't produce very understandable code. If I struggle to understand a 6 service injection with everything around it then I'm sure new devs starting on a code base will too. Get_it is much cleaner. I aim for a maintainable code base, I don't mind having multiple packages that do the same thing.
@@FilledStacks cool! I may actually try this. ProxyProvider is disposing stuff on hot reload and breaking my code lol..
@@danvilela haha I've never had that issue but that's troublesome.
@@FilledStacks Hey, just one more question. Why use provider then? Couldn~t you just use GetIt for eveything simplifying the project?
@@danvilela I wouldn't have the awesome ChangeNotifierProvider to create my View-ViewModel binding. Well I would have it but I would simply build provider and then use that. I might remove it after a while since it's only the one part of Provider that I really need.
Hey. Thanks for this tutorial. I have one question in mind. How to structure the provider if i have multiple consumers scattered down the widget tree? cant use the base view since it places the consumer right below it. Should i just go the normal way of placing the provider on the nearest common widget? thanks.
Each widget can have it's own viewmodel just like in part 2 of this video where we build a comments widget. Each widget can have it's own viewmodel, so however you need you can make and bind per view using the change notifier provider. I currently use the provider_architecture which is the code for the BaseView with some more additions to take into account responsive layouts etc. You can check the latest State & API video for a walk through of how to use that library.
@@FilledStacks Thanks a lot.
@@FilledStacks hey again. I have been playing around with the package for the last day and faced an issue. Is it possible to trigger the rebuild of a model from another model? i have two models in the same screen and i want a way for them to trigger each other. Thanks again for your amazing work.
@@ibrahimalazzawi2949 I use a service with a stream that I can subscribe too. I put a value on that stream when I want to update other models. You can also use a callback function on the service and register it in the model you want to update. You could also use the message hub to send out an update message for all viewmodels to update when the message is sent.
Fantastic. Thanks for putting this together.
Thank you. You're welcome.
thanks a lot. I found a useful way to start my own project.
That's awesome man! I'm happy that my video could help
Thank you so much for creating these amazing tutorials.
I'm new to flutter, I'm trying to implement your "Navigating without context" tutorial into this "Provider Architecture" Login and Posts example.
I'm having issue when I'm trying to replace
"Navigator.pushNamed(context, '/post', argument: posts[index]);"
because this is inside a method "getPostsUi" and I don't have access to the "model".
I have crated a function in home_model:
void goToScreen(dynamic argument){
_navigationService.navigatTo(routes.PostRoute, arguments: argument);
}
Please let me know if function is right and how to get access to "model" in Widget methods if I don't want to pass it as a argument to widget method.
Thanks for the feedback man. I'm happy that it helped you. The models are all provided with Provider so you can do Provider.of(context) to get access to it.
Thank you so much for helping.
@@yogeshbhati1359 It's my pleasure :)
Hi @Dani , I was reading the written tutorial and confused by the word called "reducing the state using data"
"Models will ONLY request data from Services and reduce state from that DATA. Nothing else". I am not clear what is reducing state is?
To reduce something means to use the current state of an object to produce a state desirable for what you want to achieve. in this case we use the state of the service to reduce the values and state required to properly show the vie that is bound to the viewmodel.
@@FilledStacks what if I have a variable inside LocationService called currentLocation, and I use a ViewModel (exp. GoogleMapModel) to update the curentLocation value?
I am doing this because the LocationService variable is shared between 2 views.
Am I doing it the right way according to your guidelines?
@@alvin3171997 I can't see it exactly but I usually make the properties get only and update through functions on the service to accomodate logging potential.
Thank you, but the starting files on the repository are not the same files you started with in the tutorials. For instance, the viewmodel folder and the locator file are not included in the starting files in the repo.
You're welcome. That's because you have to make it in this tutorial.
Hey, dude, you did a great series describing architecture. just one thing that I don't understand how did you know when to register as factory, singleton, lazy singleton? and in case of using firebase service when you register as factory you didn't dispose the firebase call while you said when you register as a factory when there is dispose. the final point in my case I register firebase service as a lazy singleton and my model as factory I sometimes get a bad error this stream has read before.
Hey man, thanks. You register a singleton when you only want one instance of a class around, a factory if you want a new instance everytime the type is requested. You have to dispose your stream subscription in the models dispose or you can creat a broadcast stream but you might end up with multiple subscriptions.
Why do you need to mix provider with get_it? can you please explain why it's beneficial? thanks a lot.
Hey you don't NEED to. I prefer to do it because i write less code and the code is prone to change when i update dependent services in A provider. In short it's easier, for me, to maintain.
@@FilledStacks so usually in your personal projects you only use either one of them or just Provider without get_it?
what is the difference between registerLazySingleton and registerFactory ? i was feeling confused when and how to use it.
registerLazySingleton is the same as registerSingleton except that it only creates the instance when it's first requested. RegisterFactory registers the type and a new instance is returned everytime it's requested. Read my dependency injection article where I give a short description of the three. www.filledstacks.com/snippet/dependency-injection-in-flutter
how to checkout the 010-provider-architecture/001-start/ only and not your whole files?
I don't have it setup like that. In the future I might, but for now you can't. I'll make a zipped version available of each repo from now on to download from the website.
Hey great video, you have many repositories in your git, which one correlates to this video so I can download and follow it?
Thank you. I think this is tutorial #10.
@@FilledStacks awesome thanks.
how to avoid unnecessary rebuilds? example:
Widget A.
Widget B.
Widget C.
Here when I update a state in Widget A with provider, the Widgets B and C rebuilds too.
So how to avoid unnecessary rebuilds in B and C ?
That shouldn't happen. The unless you call notify listeners for a UI that contains widget B and C.
Can you help me a bit? I have a home page with multiples carousels, and a want to build a widget for this carousels as they are all kind of the same (only need to change the title and they display the same kind of widget card) I need them to reach my webservice for pagination, how should I go about their state managment I mean the data source arrays, should I put each array and calls to the webservices at the home view model? I would really apreciate if you can help me to make this decision
Hey there. There's nothing special i would do. I'd have a model for the widget that manages the state. On construction I'd pass in the title and the url for the data to fetch. That's about it. The rest is ui code to build the widgets functionality
@@FilledStacks oh right I see. I added the arrays at the home view model, I call my api.dart there as well to update each array but I think your solution is way better as I wouldn't need to create a new array and method in the model for each carousel. Oh right man THANK YOU A LOT. I really think someone as kind as you is set to success thanks for replying all of our comments
@@AllenWillian That's a very nice comment man. I appreciate the honest feedback. Thank you for the well wishes, I really like teaching mobile app development. Let hope for some magnificent growth of the channel so that I can do a bit more to help out other devs.
I have been looking for this ! thank you!
Awesome! I'm happy you found my video :)
Is this the MVVM architecture?
It's based on MVVM.
how to show user based post?? Means other user can not delete post.
I don't know what you're asking. if you want only sepcific users to see a post then you have to add visibility indicating values so that you can filter on the backend based on which user is requesting your data.
@@FilledStacks I need to hide delete button for those who is not owner of the post.
i mean to say when post.userId != currentUserId hide delete button
@@manishakushwaha1577 Then you should do that haha, what are you asking me? you put the statement above. Just use that to check if you should show the button or not.
Isn't it better when using Provider.of(context), with listen argument set to false: Provider.of(context, listen: false), to prevent it from unnecessarily rebuilding the widget. I am still learning, need clarification :)
I read the documentation of Consumer at: pub.dev/documentation/provider/latest/provider/Consumer-class.html. There it says: "Unless listen: false is passed to Provider.of, the widget associated with the BuildContext passed to Provider.of will rebuild whenever the obtained value changes. This is the expected behavior, but sometimes it may rebuild more widgets than needed." I tried to set listen:false on your tutorial, and it works fine.
Yes, that's not fine. I won't say it's better. I'd say it'll not rebuild when that value changes. If that's what you want you should set it to false. Similarly to using a .nonReactive viewmodel builder in the latest tutorials. It's all dependent on what you want.
Hi filledstacks, thanks for such a great tutorial. I used to develop apps in react native where the architecture was well defined using redux for state management and redux persist for persisting state.
I was wondering how we would persist state like lets say i want to persist user data and then on app start refresh it and send user directly to home screen.
Thank you :) You can use shared preferences. I have a short tutorial on it here www.filledstacks.com/snippet/custom-startup-logic-in-flutter/ . It uses shared preferences available on ios and android to write content to disk as string and allow you to read it up after. That tutorial covers exactly what you want to do. I hope that helps
Thanks a lot :) Do you follow the same file structure for bigger apps where there are a lot of statefull/stateless widgets in a single screen.
How about grouping the widgets specific to a screen in one folder.
Like
Screens
- screen1
- widgets
- widget1
Widget1_view.dart
widget1_model.dart
- widget2
Widget2_view.dart
screen1_view.dart
screen1_model.dart
-screen2
.
.
.
In this way we can have all the widgets (both statefull and stateless) in a screen that may or may not need a model in one single folder of that screen.
Widgets in the widget folder inside the screen folder will be screen specific widgets only.
All common widgets will be in the shared folder.
@@vinitkadam_ Sounds good with me, I usually group it like that, sometimes I try something different. Widgets in their own folder, under UI. I'm still trying to figure it out as well so I'm trying different things for every project.
I really like this tutorial, and it looks like a great solution, but I have two questions:
1. How do you share data between views? I've always thought of state management as a solution to share data across your app, but this tutorial doesn't really cover that.
Let's say you decide to add a user_profile view to this app. In that user profile, you want to show how many posts you have made. But the data is in your home_model, so how do you get to it without passing it through the navigator?
2. I see you give widgets their own viewmodel as well. If you decided to add business logic to the post_view, would you move the logic in comments_model to a new post_model? Or just keep it as a nested viewmodel?
Thanks so much!
Hey there, it's pretty awesome. I've made v2 of this architecture it's part1 of the latest series Im posting.
1. To share data between viewmodels you make a service. I have a full video about that.
2. I'd keep it in the widgets model if that logic will be required for all instances of that viewmodel. If it's only required when it's in a certain context then I would move it one level up, out of the widgets viewmodel.
@@FilledStacks Thanks man. I noticed you reply to every single person here, that's awesome. Looking forward to watching your stacked videos. Subscribed!
@@hojdog You're welcome :) yes. I try my best to reply to every comment that I get. i think you'll like the stacked series if you like this video. Let me know what you think when you start watching it.
@@FilledStacks having been through your latest videos, I find it too complex as a beginner. There are so many dependencies to get everything working, just for the sake of keeping the logic separate from the presentation code. I don't think keeping the logic in the widget class is really an anti-pattern given that the presentation logic is in a separate build method already.
I think i'd like to revisit your architecture when I have a bit more experience.
@@hojdog yes, I think that's the right move on your side. See how a code base feels and works over a year or two when you have the logic mixed with your UI then you make that decision. But your observation is correct, i literally do everything I can to keep the uI and the business logic separate so that I can unit test all my business logic and swap out UI's without being concerned about any logic. It also works very well in teams. If you don't see the benefit of it you definitely shouldn't be using it. I use it because we build 6-9 apps a year, other teams has to inherit the code when we're done with the base setup so having an architecture in place with clear guide lines will make it so that when they inherit a very large application they know exacly where to go to change something and know if it has dependencies on anything because it'll be clear from the viewmodel and service separation.
Hi, I need your help, I want to show "statusCode" and "reasonPhrase" on the top of the PostList UI(home_view) but I don't know how I can pass that from api >> getPostsForUser(int userId) method with the List.
Future getPostsForUser(int userId) async {
var posts = List();
// Get user posts for id
var response = await client.get('$endpoint/posts?userId=$userId');
int statusCode = response.statusCode;
String message = response.reasonPhrase;
var parsed = json.decode(response.body) as List;
// loop and convert each item to Post
for (var post in parsed) {
posts.add(Post.fromJson(post));
}
return posts;
}
That should be a separate request that gets that information separate from the posts request. If it's all in one request then update your serialisation to a model that contains the list of posts and the reason and status code in it and return that to your viewmodel
@@FilledStacks Thanks for quick reply. I was also planning the same thing. Now I'm more confident. I was also thinking that using FutureBuilder + Provider is not good approach as we are already doing setState and logic in viewmodel. Please let me know if I'm on right path. If not then, in which use case it's good to user FutureBuilder with this provider architecture.
@@yogeshbhati1359 Hi Yogi, I don't use anything else to manage state besides the View->ViewModel binding. The new Stacked package has a FutureViewModel and a StreamViewModel which basically does what Stream and Future builder does but for the Viewmodel. That's what I use now.
@@FilledStacks Thank you so much for your guidance.
@@yogeshbhati1359 You're welcome yogi :)
Hi sir are you used mvvm architecture for this right?
Hey, yes. The stacked package has all this code and it uses mvvm
Bro i really love your tutorials. But I have one request from you is that Try to explain in more simple and in details :)
Very happy you love the tutorials. I do explain in the most simple details if you understand programming and object oriented principles. If you're a beginner in programming then these videos are not meant for you :) I don't intend on explaining the basics of programming at all. But there are a lot of good youtubers out there that cover the basics of object oriented programming
Great tutorial brother, just one thing can you please make a short video in which you can show us using flow chart how "provider + get it" exactly works it'll be a lot easier to under how these things work in a widget tree. Thanks
Thanks :) I don't think I'll be able to do that. Look up InheritedWidget in Flutter to understand how provider works and for get_it. You're simply storing references to an object (singleton) or references to a function that constructs an instance of an object. It's a short implementation. Basically a Map and you store the instances in there that you want to access later.
@@FilledStacks So basically get_it is used for storing instances of provider like kiwi ...
@@yashinherenttech6396 No not instances of provider. Instances of the types you want to retrieve later, or the functions that create the types you want to retrieve later.
@@FilledStacks Oh okay thanks. Understood !!
Is it okay to use the dio package in place of http.
Yep, I use dio, http and requests in different project. If it fits your needs then you should use it.
@@FilledStacks Thanks I really appreciate the fact that you make content like this available for free.
hello cordial greeting, thanks for the tutorial, in reality it has served me a lot. but I have a problem when I use Navigator.pushReplacementNamed () to avoid the return to the previous screen, when I signout and return to the login and vicebersa, I get the following error: A HomeModel was used after being dispose. Once you have called dispose () on a HomeModel, it can no longer be a user.
I appreciate your help
Hey thank you. I'm happy to hear that it helped. Your home model should be registered as a factory in the Locator not a Singleton.
@@FilledStacks Great🤩, locatorService.registerFactory(() => LoginModel());
locatorService.registerFactory(() => HomeModel()); Thank you very much.
@@FilledStacks sorry dude I also register my model as a factory and i got the same error when i navigate to second page and when I am back to first page then try to go to second page again i got this error
@@mohabmagdy4155 Did you remove the dispose code from the base view?
I am getting this error
[ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: FormatException: Unexpected character (at character 1)
please help me out from this error
Seems like a format exception. Your compiler should tell you where it is.
Awesome tutorial. I'm having an issue with home_model. The List posts is null even if we call model.getPosts. I printed the list inside the function and I'm getting the values but posts is not getting the update.
Nevermind. I found the issue. I have a different question. Why do you use locator().userController on the StreamProvider instead of locator().userController.stream? The StreamProvider states that we need a Stream, not a StreamController.
Nevermind again, hehe. Sorry. I was looking out the project and I see your project is using Provider 2.0.1. On provider v3, we need to pass a stream.
When you can solve things after asking a question is the best. I do that on Stackoverflow sometimes. I'll post the question after hours of trying, 5 minutes after the question is up I figure it out then answer my own question haha
How did you figured it out @elhe26 ?
Because I am getting the same problem, the UI is not updating! Therefore getting the null message.
Hi, first good job on this tutorial I really liked it and it helped me a lot, second, I used the architecture as in your tutorial and I have a question about the user provider, I need to change his attributes sometimes and my question is where to handle this in the model or the view?
Hi, thank you. Any business logic or state management should be done in the model. The view should only pass data to the model that the user enters. No logic in the view, everything in the model.
@@FilledStacks So just pass the context to the model
and do Provider.of(context).SETSOMETHING = SOMETHING ?
@@danielrachlin9226 No the context should never be available in the model. the model only has business logic, it can't have anything related to the UI. Have a function on the model model.updateUser(String username). In that function you'll use the user service to update your user.
userService.updateUserName(username)
Then in the service you'll do the update to your current user. When you're done you'll call notifyListeners to update your model if needed.
and what is the diffrence between a registerFactory and registerLazySingleton
If you register a type as a Factory you'll get a new instance back every time you request the type. If you register as a singleton you'll get the same instance back every time. More details description here under the setup. www.filledstacks.com/snippet/dependency-injection-in-flutter
Try changing the type of the left hand side, or casting the right hand side to 'Stream'.
builder: (context) => locator().userController ,
why this error ??
here
builder: (context) => locator().userController ,
Because you're supplying a controller where you have to supply a stream. use controller.stream instead
@@FilledStacks thanks a lot man for replying , anotther errror, No route define for /post ,why is that !
cant find the solution
waiting for your reply
Can you make a video just about the locators(get_it) why we need it and how in details? Please.
I don't think there's enough content to cover a full video but I might do a short one. It's just a normal dependency injection container. You don't need it, but it's easier to use then inherited widget. There's not much else to say besides it's better than inherited widget to me because I don't have to make sure a widget is wrapped in an inherited. With this method you can get the object you need anywhere, even in other services that don't have the context for you to get your inherited widget from. I wrote a short post on how to set it up here. www.filledstacks.com/snippet/dependency-injection-in-flutter . Read up on Dependency Injection as a whole, then you'll see why I use it.
@@FilledStacks Thanks bro. Can you have a look at this issue : stackoverflow.com/questions/56191354/flutter-transition-new-page-reveals-below-old-page-elevated
I could not get a solution to this. Please help if you can.
Hi man. Seems like you're just having a transition issue it's hard to imagine a transition based on words so you'll just have to play around with it or maybe someone has made the same thing already. Like this pub.dev/packages/page_transition
I was missing the setupLocator function in the main function and was getting the error of "Invalid argument (Object of type RegisterModel is not registered inside GetIt." I think this error is misguiding us. Either mention in the get_it package documentation, while registering the Model class or mention it as a second step that Model class must include SetupLocator in the main.
github.com/fluttercommunity/get_it/issues/37
setupLocator has nothing to do with get_it. That's just what I call the function where I collect all the service registrations. The readme does mention you have to register a type before you can request it. That's how I knew to call setupLocator before the runApp call
How does one go with a view with multiple models? e.g. having a test page with all API's available. Thanks for the awesome video btw!
Thanks! much appreciated. You would never need multiple models. A model is a one-to-one relation ship with its UI part. If you want multiple widgets with models then just make a normal widget and give it it's own model and put it in the view. But the view will still have one model. Model just directs anything it wants to do to a service, so everything you want to share should be in your services. Your multiple API calls will be in your ApiService. You'll just call the functions from the model.
@@FilledStacks This. This is what I actually did. Thank you!
@@FilledStacks so what about when one view needs the state stored in the model of another view? Shouldn't it be possible to nest models within a view? Say for example I'm working on a multipage form and on the last page I need to collect all the state data of the previous pages into one big object and send to the server. Isn't that a perfect candidate for letting the last page gain access to the previous page's models?
No. As I show in part two of the tutorial, the second video, you create a service that collects your info and then you share that between the models. Models never have to be kept inside other models unless it's a dynamic list of models that need to be created. And even then there's other ways of doing that.
@Ridwan Azmat
This is gold! Thank you so much!!
You're very welcome :)
This exception shows up wehen ever I try to run the app
The following _Exception was thrown building MyApp:
I/flutter (12226): Exception: Object of type AuthenticationService is not registered inside GetIt
And you checked if it's registered in the locator?
@@FilledStacks turned out I didn't add setupLocator() before void main
Very elegant work thanks for sharing that
Thank you 😊 it's my pleasure
Not a programmer but tried to learn Flutter. On building my first app, should I immediately apply this architecture (provider) ? Is this concept for the beginners?
No, definitely not. Learn Flutter first, follow the docs. Build everything you need from there. Everything.Only when the code becomes messy and a problem do you introduce state management.
@@FilledStacks thanks for your response. Is using setState() or inheritedWidget will be enough for a beginner ?
@@manecioputik7668 That should be all you're using for now. Watch my video From Set State to architecture on the channel. I explain all that in there.
Hi @filledStacks i love ur architecture and i am currently using it and God bless you for it.....Can u consider to architect flutter_bloc since it include provider now.? thanks
Thanks man. I'm happy to hear you're liking it. I'm not a fan of BLoC so I won't be using it or showing anything about it. It's a bit too complicated and around the way for me personally I like the more straight forward approach to app development that I've set out. No extra boiler plate, no additional constraints, just requirements and services that perform them. That's a long way of saying I will not be considering making a video about bloc, resocoder and robert brunhage have some very good tutorials on it that you can check out 😊
Is this architecture still good with provider 4+ nd latest get_it? Soon Starting my first app.. Nd this is the only that makes sense to me.
Yes, I've moved all the base widgets into a package called stacked which you can use so you don't have to re-write the base widget. My new architecture tutorial goes over that.
Bro after login. How to fetch data of current login id by pressing button. Please help me to solve it
when you tap the button call the api endpoint that returns your data.
@@FilledStacks tnq bro
This line is not working on modern Android studio setup in start directory:
(If I comment this line, all seems ok)
Compiler message:
lib/locator.dart:3:23: Error: Getter not found: 'instance'.
GetIt locator = GetIt.instance;
^^^^^^^^
You should update your provider version and then see if the instance is still on there.
Very good video!
Thank you. All of this has been neatly wrapped up in the stacked package.
Very awesome tutorial! Keet it up
Thank you. I'll try my best to do so.
Good job man! Keep it up!!
Thanks for the positivity. I appreciate it. I'll try my best. The firebase series is om it's way 😊
Awesome as always!
Thank you.
I think now I already can repeat each word of this video one by one with eyes closed, a must seen video ;-) ... I'm wondering, when the video for Stacked (pub.dev/packages/stacked)? hehe, thank so much Dane, so inspiring!
haha That's awesome Daniel. Thanks for watching! I have just finished the base architecture with some written parts. The first video will come out on Sunday which will cover everything that was done in this video for the bases then I'll do an additional few episodes to go into every detail of the architecture and how to extend it for your own app.
@@FilledStacks yuhuuu!!
Is your build developed with flutter?
Yes. In this video I use Flutter to show the architecture.
@@FilledStacks Sorry ,I meant your website
No, the website is made with gridsome. a vue js bases static site generator.
there are errors in the code(package:provider_architecutre???), some of the code, as well as packages, are already outdated and do not work, it is completely unclear on code inserts which file is being edited and in which place(it is easily solved by line numbering and file name) this is terrible material for learning(text version)
That makes total sense. It's 2 years old, and this has all been wrapped up into a package called pub.dev/packages/stacked which we use for all our clients.