Navigate without Context in Flutter | Flutter Navigation Service Tutorial
VloĆŸit
- Äas pĆidĂĄn 7. 09. 2024
- In this Flutter tutorial we go over the process of moving your navigation logic out of your UI file into the business logic file.
đ Written đ: filledstacks.co...
Starting Project: firebasestorag...
I think this is possibly the first time I have seen any Flutter author on youtube present important aspects of software engineering especially SOLID in the way that you construct your videos. Ive done everything you have mentioned here when I first started developing with Flutter, my background being C#, Java, Xamarin & specifically MVVM & reactive apps. Judging by your content, something tells me you have a similar background. Either way - great to see this type of content on Flutter. There are way too many Flutter channels that try and show 'Flutter challenges' with very poor design & mixing business functionality in the UI thus making testability a nightmare - your content is great, unique & truly inspiring and despite what others have said - 'definitely not too fast in the way you explain things' - looking forward to watching more of your content....
Thank you very much for you thoughtful comment. I really appreciate it. You have made a very good observation. I started with Java, then went to C#, C++ for cross platform game dev when i worked at a game dev company, then onto Xamarin and Mvvm Cross for over 20 mobile apps so it's instilled in me to focus on coding principles, architecture and especially the SOLID principles. I agree with you that there's not enough of this kind of content which is why I'm focussing on that. I'm happy to hear you're in the Filledstacks community now. It'll keep me on my toes and if ANYTHING could be done better or in a more thoughtful way that I present i look forward to hearing the feedback and learning from you too. Thank you again for the comment and the feedback. â€ïž
you said almost every thing i wanted to tell.
keep up FilledStacks.
@@BuzaBuza Thanks I'll try my best.
One of the best flutter channels in youtube , thanks very much â€ïž
Thanks for the love man đ I appreciate the positive feedback.
Niice. Thanks for this. If I continue watching your tutorials, I may end up changing all parts of my appsđ
Haha, that would be awesome. I'm taking over your code base !! đđ
@@FilledStacks I have already started this work. I am still very early in the project so the refactoring will not take long. Good thing I am seeing this channel now....
đđ it's a good thing you found my channel so early đŹ onto the refactors đ
Same here i used this great man archicture for all my projects and IAM refactoring the old projects to the atchicture.
@@mohabmagdy4155 nice! I'm yet to run into situations where it's not capable of delivering :) I'll be sharing some more architecture tips in the future once I've used and tested them in production.
My #1 Flutter wisdom channel. Keep it up, mate!
Thanks man! I appreciate it.
Great! This is exactly what I did in one of my projects
Awesome! Thanks for letting me know. There's another way to do it where you don't even need the navigator key. I'm wondering if I should make another video for a different implementation. The exact same setup as the dialog manager video.
@@FilledStacks that'd be great! I'm curious to see how you'll do it :)
@@FilledStacks Did you ever release this video without having to use keys?
@@g-luu No, but I use this in production now (pub.dev/packages/get ) which is navigation without context or keys.
I think one of the best flutter tutorial channel !!! Appreciate that buddy !!!
Thank you for the kind words man đđ I appreciate it.
woow, very usefull for Firebase Push Notifications click handling without context
yes. definitely.
Jaja, i never thought this even existed. Thanks for teaching us this things FilledStacks
Happy to help :)
One of the worst things I hate in flutter is navigation and mixing the UI with Bussiness logic, I should thank you for your smart solution.
You're welcome. I found the same problem which is why I came up with this. It's much better once it's split up.
Awesome video! Something that has been on my mind is why not inject context as a dependency for your viewmodel? That way things like Toast/Snackbars and navigation can work properly. (I haven't done it but curious to read you opinion). Thanks
I want to know too
The viewmodel should be pure. I don't inject The context because it's UI related. That's just my opinion when it comes to single responsibility. My viewmodel handles state and decisions made for the view, nothing else. It shouldn't know about the context or even have access to it, that's why the view file is there. It shouldn't even know about other views. That's just how I've found maintenance and consistency in a code base to be easier to execute on over time.
@@FilledStacks gotcha "separation of concerns". Makes sense, it also takes discipline to keep it that way. I've def struggled with parts of my app where i needed to use context for one thing or another. Thank you for the explanation, keep making awesome videos!
@@partisan-bobryk It definitely does. During prototypes and POC's I usually Hack away and don't bother with setups. It's only when I concern myself with long term maintenance that I refactor and do something like this. Thanks for watching
Thank for the great tutorial đđ
It's my pleasure!
That's a clever way to use route constants (as routes). Feels better than having a class RoutePaths
Yeah. I also didn't like that so I started using an alias for my constants. It helps with readability.
Dude sounds South African. Great tutorial my brother.
Haha that's because I am đđżđŠ thank you đ
Amazing channel, the best in the world.â€ïž
Well that is very kind of you to say! Thank you. I really appreciate it.
Interesting! Thank you for sharing your approach and ideas!
You're welcome đ
@@FilledStacks I don't know if you wanna hear/read this from anybody else but a pretty woman, but - man: I'm gonna spend the rest of my day with you!! đ đ
@@RobertWildling hahaha It's uncomfortable to hear that, but I'm fine with it! đ
about passing arguments, how to pass multiple arguments? because in the example you only showed one which is a String
The exact same way đ you're passing an Object, so you can simply make an object that contains all the values you want to pass to you class, cast it to that and pass the full class.
I am using architecture you explained here. Best explanation †can you please explain if I enter data on Home Screen from text field how can I use that data inside text widget on first screen?
Hey, you should save that data to a service so it's accessible to all your ViewModels through depenency inversion.
Great thank you for quick reply, I will do the same
Hey, love your channel and your tutorials. Would you be interested in doing a Complete beginers guide to streams, sometimes i find myself in a dilema what to use stream or future, i know what they do but both can achive the same result. Just a suggestion, thanks for all the work you do, it is much aprechieted!
Thanks for the feedback. I am planning on doing something around streams, similar to my future video. They're not used exactly for the same thing but they could be. Streams are when you're expecting continuous updates. Futures are once of actions that run asynchronous.
You are a genius.
Haha, I wouldn't go that far, but I don't shy away from compliments so Thank you đ
I was doing dynamic link for firebase as per your video, and i can not navigate to other pages due to no content from service.
Help please. A simple way to navigate without context.
Use the navigation service from the stacked_services package like shown in part 2 of my latest architecture series.
Hi not able to get current route name using "navigationService.currentRoute" how i can get current route name without context. I am using stacked_services: ^0.8.5
You have to add the stacked navigator observer. There's a part about it in the readme.
i'm currently building a project with stacked package and i needed to do a bottom to top transition so i used
locator()
.navigateWithTransition
and it works great , but i don't understand why you make it pass a widget instead of route name like the navigateTo function
There's two functions. One with the widget and one with the route name. I think.
yes true but the one with route name doesn't accept custom transition
I wish I can give more than one like
Haha, sometimes I feel that too. I'm happy you like the video.
Nice work. Would be interesting to see how to handle deep links with this architecture đ
Thanks. Same as you would normally đ you're still using named routing so you can set all that up in there.
Great video!
i'm curious about what Remi would suggest as alternative approach, yours discussions about it was at github or somewhere else that I could read it?
Thank you
We didn't discuss navigation without context in particular. Our main point of discussion was using getIt in combination with provider because Provider's dependency injection becomes very messy over time.
This discussion I read some days ago when searching other thing, I think hahahaha a topic about a refactoration Remi did in a exemple
Thank You for ansering :)
@@gustavospaki7988 It's my pleasure. Thanks for leaving a comment and checking with me.
Appreciated.
happy to have helped.
can I do this using a routing package like `auto_route`??
Yes you can.
thanks, Is it possible to use both getit and provider in the same project?
Yes, I have a video where I show my setup. I use it like that. This architecture video ( czcams.com/video/kDEflMYTFlk/video.html )
Could you expand, please, on why he feels it shouldn't be done this way?
I don't want any business logic in the UI files. I want my UI files have the single responsibility of being a UI. User Interface. It must render everything based on info and it should take user input. EVERYTHING else it does breaks that rule, i think navigation should happen where your logic happens. The same with showing alerts or dialogs.
Do you actually use this navigator service on your real world projects?
Yes. I use it. Everything I share I use in my app. It's all from refactors I'm making in production apps that I'm building.
How would you edit the navigateTo function if the routeName requires a parameter as well?
I would pass in the arguments as you would for the normal navigator.of() navigation call.
Thanks for all of these tutorials you provide. Very instructive!
Regarding this tutorial, I was wondering whether you think that injecting the navigator services in your ViewModel makes it less reusable ? Let's say you want to re-use your ViewModel in a flutter web project which would likely use a different navigation flow... Then injecting the navigator services will be problematic, won't it ?
My guess would be to inject a kind of "navigator view model" that rely on the navigator services. The navigator "viewmodel" would have method like "navigateOnSignUp", "navigateOnSignOut", and those methods would have different behaviors depending on whether it's web or phone project... What do you think? Did you already face this issue ?
Thanks :-)
You're welcome :) I'm happy to hear that you get some value out of the tutorials. The reason I write the code this way is to make it more re-usable withing other viewmodels, service, platforms etc. I use the exact same service in my Flutter Web projects with no problems :)
Hello, thanks for the tutorial. I am however encountering a problem. I copied the Navigation Service code from your website, but both methods give me an error: "The method 'pushNamed' can't be unconditionally invoked because the receiver can be 'null'."
Sounds like you're not following null safety guidelines. You can't invoke something that can be null without checking if it's null first.
Fabulous work FilledStack. Combining this with startup logic works like a charm, but the start-up logic doesn't seem to work with Flutter web.
Great news!! That's strange, i still use startup logic in Flutter web. Although firebase current user always returns null I know it checks there and navigates appropriately.
@@FilledStacksThanks for a quick response. On the mobile everything is working as expected but on the web the navigation is working still but not checking if the user has already logged in. Therefore ending up on the login screen Everytime.
@@DemsDema Yeah, that is pretty strange. You might have to use something like Route_guards instead from the auto_route package for web. I haven't been working on it in the latest releases so flutter web might have had some behaviour changes.
@@FilledStacks Alright, let me give that a go and will let you how it goes. thanks
Great tutorial but i am unable to use popUntil using this approach, all the route names are null.
Thank you. Are you supplying the route name to the settings?
Your architecture is excellently simple, completely fine for the complexity of a typical mobile app. In your example there is a caveat, though. After login you navigate to the home screen, so far so good; but, then the user can press the back button and your application jumps back to the login screen without logout. So, eventually your application can be brought into an inconsistent state with the back button. How can you handle that? I'd appreciate, if you can show or explain your solution to handle that finicky back button. Thanks a lot.
Thank you. That would be based on a universal check for me that overrides the back button. It's not a common problem, most apps have long lived logins. If your problem is pressing back and going to login screen then I'd suggest doing a replace and not a push this way when you press back the app won't go back to login. Instead it'll just close since the new view is the only one on the stack.
@@FilledStacks Thanks for the comment. Replace won't work since I'd love to keep the possibility to logout and navigate back to login. In your example, how can you prevent the user back-stepping without logging out?
@@miklosnemeth8566 In the BaseView I would wrap my Scaffold with a WillPopScope, that would check the AuthenticationService which will tell it if it should allow the back press or not. The BaseView and Services, is based on my Provider Architecture setup using get_it. My first Provider Architecture video.
@@FilledStacks Excellent, this would make your sample complete, sure.
What plugin highlights the different widgets with lines?!?
Dart Code. Open up the VS code settings, search for FLutter UI and enable both options.
Hi Iâm a beginner in flutter.
May I know whatâs the benefits of doing this instead of using Navigator.pushnamed like your previous tutorial?
You can't do Navigator.pushNamed in the model because there's no BuildContext. There's no build context, because a viewmodel is only meant for state and logic, no UI related code. Therefore it cannot and should never know about the BuildContext, even if it's just importing or passed as a parameter.
First of can i ask what vscode plugin you are using that's giving that tree-line-trace(- - - - -)
I'm using Dart Code. Open up your preferences, search for flutter UI, enable both options that come up
This approach is great!! I just wondering... should I use this approach with all my routes? Or should be better mix context routes with this global key routes?
We use named routing through a service for all navigation including bottom sheets and dialogs.
@@FilledStacks understood!. But, is there a problem if I have two navigators on my app? One for my main flow using context, and one for one page behind bottom navigation bar using global key [or even another context] ? Thanks so much for the answer!
@@amandacleto8396 No, we have multiple. We use the indexed key in the Navigation Service to help us with that.
@@FilledStacks thanks so much, you have just helped me a lot!! đ
is there way to reload model data when poping back
Await the call in the model you're coming from. When that future returns (when you pop) call notifyListeners.
how can i use this navigation service with provide proxy and without locator
register it as a nonDependent service in the multi providers and then inject the service like any other. watch my provider architecture v3 if that statement is confusing.
I did i also posted the issue on slack filledstacks.slack.com/archives/CJY4SV5KQ/p1575982155363100?thread_ts=1575982155.363100&cid=CJY4SV5KQ
Register getIt error is coming everytime
read the error properly, figure out what it's saying and then fix it.
Sailor package does all of this for you, check it out!
Thanks, I'll definitely check it out.
What if I want to navigate to a screen, then return a value when I pop that screen?
Watch my named routing navigation video. You can return a value when you pop and you'll get it where you called and awaited the navigation.
According to me, i find it too hard to understand.
That's a shame. You're the first one to mention that. If you understood the concept then it should be easy to recreate in a simpler way.
Hey! Your tutorials are great.
I just want to give you some feedback, you are too fast, for a beginner, I am too confused what you did and why you did that!
It would be great if you could explain the problem first and then try to explain the solution. Also the classes you use, what is their responsibility, that we people can understand better.
Great tutorials anyways.
Hey Thank you for the feedback. I appreciate it. Unfortunately my tutorials are not meant for total beginners. I also won't specifically focus on beginner stuff unless it's required as an entry to the topic I want to discuss. My tutorials are focused on getting devs that's familiar with Flutter and programming in general to a point where they can architect their own apps using the patterns I'm mentioning or teaching directly. I mention the responsibilities of every class i construct in all the videos since single responsibility is one of my main focus points. And about the speed, I'm not a big fan of slow tutorials so I won't be making those. I tend to watch on 1.5 or higher to skip all the unnecessary info. I hope you understand and still stick around and watch my vids đ