Flutter Bloc & Cubit Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
block is a well-known and established library when it comes to state management in flutter it promotes good practices such as immutability and it has one of the best ecosystems of supporting packages and documentation built around it in spite of all these benefits using the block package is painful at times and the cost is none other than boil plate the version 6.0.0 and upwards of the block package comes to make this library palatable to the masses it gives you the ability to use a lighter version of block called cubit and it also removes a bunch of boilerplate [Music] hello welcome to risokoro where we are getting prepared for real app development so that you will get freelance clients or a job and be confident about the apps you build so subscribe and hit the bell to join us on our quest for becoming in-demand flutter developers in this tutorial we are going to build a rather simple app and we are going to implement it both with qubit which we could call a lighter version of block also and then with block the core one itself it's going to be a simple weather search app where you can enter a city name or even some gibberish but i'm going to again enter london just for the sake of an example and it's going to give you a fake temperature in your particular city or it can also show you an error message with a snag bar that we couldn't fetch whether this is also just a randomly a chance that it's going to show an error message instead of regular data also this tutorial is suited for both beginners who would like to learn qubit or block from scratch and also for developers who are already kind of experienced with block but they would just like to learn about qubit more or maybe even just some of the changes which came out with the version 6.0.0 also we do have a star project prepared right here which includes some of the boilerplate which every single flutter app needs for example this main.dart and we also have the ui already pre-built the only thing which is not yet built is the qubit or block part of this app so that means that the state management is not yet built so if you would like to get this star project to get going with this particular tutorial be sure to check out the written tutorial from the link in the video description where apart from this startup project you can also find all of the code written in this video links to the libraries links to some resources which i'm going to be mentioning in this video and also you are going to be able to go through this tutorial at your own pace in its written form so let's take a look at the already implemented classes so here is the ui we can show initial input the loading indicator which you could have seen here this is the input loading indicator is displayed right here and so on and uh yeah so here is the input and that's about the ui you don't really need to focus that much on it we're going to come back here once we actually have the qubit or block implemented but what's more important for us right now at the beginning of the tutorial is the weather model which looks like this it's a simple class it has a city name string and temperature celsius double field and it also has overridden equality to make it value equality as opposed to the default darts referential equality and then we also have a weather repository already implemented which just simulates network requests it has one method fetch weather which accepts a city name and then what we do here is that we just delay the execution by one second and then we simply generate a random temperature as you can see right here and we also have a chance 50 that is to instead throw a network exception which is going to trigger that snag bar from the bottom which will inform the user that there is no network before we jump into implementing the qubit and block for this particular weather app let's talk about qubit and other basically immutable state management solutions from a high level perspective because although there is just way too many state management packages right now on the flutter scene it all comes down to the basic decision of having either mutable or immutable state so we probably all get started mutating individual fields inside a state object of a state full widget or inside a change notifier right so you can have something like this my change notifier this is by the way coming from the written tutorial so definitely check it out if you want to copy this code yourself and you have a change notifier with two fields and whenever you change a state you trigger some action you just mutate that field in place to a new value and then you notify listeners in the case of a change notifier or in the case of stateful widget you would just call set state but it's basically the same thing you have a mutable field and then we have an immutable equivalent of this simple change notifier which we can build with cubit and it's going to do the same thing but instead of overriding fields in place it's going to basically generate a new copy of these two fields which has a bunch of benefits so if we go ahead into the pubspec dot yaml file and we add qubit as a dependency or actually we are just going to add the block package and the flutter block package as dependencies because block is built on top of qubit that means that having block here also adds cubits together with it the same goes for flutter block so once we save that get all of the dependencies and come back to main.dart how would we be able to build this sort of a simple functionality with qubit well instead of having the state that means the fields and the thing which controls the fields in just one class we would have two classes one would be for the fields we call it state and the other one would be the qubit which will uh change the state so let's go ahead i'm again just going to copy the code from the written tutorial because this is just a simple brief explanation we're going to delete it in just a bit but basically we have my state here just make sure to overwrite equals and hash code when when you're implementing this for real and not just for an example and then we have my qubit we import qubit over here and as you can see it looks suspiciously similar to the mutable change notifier but what is quite different here is that the fields are inside a separate class from the qubit the qubit holds only the change state method which tells the qubit to emit a new instance of my state which has fields set to 0 and new value whereas the initial state of the qubit which is passed into the superconstructor has my state containing zero and initial value in both cases the second field was changed to new value right both here and in the change notifier the same thing happened we have updated the second field basically but whereas in the change notifier we have truly updated the second field in place we have mutated it in the case of qubit or block also what we are doing is that we are emitting the whole state both of the fields at once and this enables very simple way to track history of state changes just like you have a history in your browser you can have the same history of what kind of a state was there previously in your mobile app and then you can just revert back to the previous state in history that is very easy to do with immutable state and also there are many more benefits and you can learn about them more in depth from the tutorial from the cart in the corner now just a brief side note for advanced users of the block packages trying to understand qubit and how it works so you can see that something is missing here compared to block and those are events instead of having events we have simple method called change state which then updates the state or should i say emits a new state that's basically the only difference as you can see right now on the screen qubits has functions whereas block has events but this seemingly simple change has far reaching impact while it simplifies code quite a bit you lose the ability to easily track incoming events so if you would like to perform something called event sourcing you should definitely choose block over qubit and if you would like to learn more about event sourcing and all such things there are links to everything in the written tutorial so check it out from the link in the video description if you're completely new to this package and to the block pattern itself don't worry because we're going to cover everything in this tutorial this was really just a note to the more advanced users who may be looking for events but they are just nowhere to be found in this simple example cool so let's now delete these uh examples of change notifier and qubit and let's build this app for real so while we have already added the block package to the pop spec yaml which also adds qubit as i've already mentioned the next step is to create the weather qubit and weather state again we want to have separate classes for state and for the qubit which emits new states now we would be able to create these classes and files for them fully manually that's completely possible but there are also handy extensions for vs code and intellij again links to them are in the written tutorial so if we have a chance to use such extensions we should definitely utilize it so for vs code at least which i'm using right now it's called block just search for it in the extension tab and here you go block from felix angeloff just install it and once you have it you wanna right click on the lib folder and we are going to say cubit new qubit let's give it a name weather just like that and it has successfully generated weather cubit which is awesome now we can expand this thing and you are going to be able to see that we have whether qubit.dart and whether state dot darts as a rule of thumb i always create the states first because when you think about it states are the reason why you want to create a qubit in the first place right because without a proper representation of the state of the qubit you just cannot possibly write the logic that will emit these new states so what kind of a weather state do we want to have well we are going to create weather states multiple ones for a asynchronously loaded resource right because in the weather repository we can see that when we fetch weather it returns a future and this means that in the ui we need to represent the initial state which is already created here by the extension which will represent the state for when the user has not yet taken any action aka we just want to show this initial search bar and nothing more no temperature no error messages nothing just this initial search bar that's the initial state and then we want to have a loading state which is going to be emitted whenever we are waiting or waiting for the future to complete and then two next states which are going to be present here are the successful state when weather was loaded successfully and then an error state when we got a network exception instead so this means we have four states that are going to represent in total so let's do just that actually we are going to add a constant constructor to this weather initial just for uh the purposes of really just probably premature optimization but hey constant constructors are really cool we are going to be we also need to actually add it to whether state to the superclass like this and also if you would like to learn more about constant constructors and constants in dart you can do so from the tutorial from the cart in the corner now that we have that the next state should be class weather loading which extends again whether state and again it's going to have a constant twitter loading actually we can just copy this the next state will be weather load bit you can hit control or command d to select the next occurrence so load dit at least on vs code that's how it works and this very low did will not be just an empty class because we actually do want to hold some actual state field in this particular class that is going to be a final weather which is our weather model class let's call it weather and let's add it to the constructor like that and now we need to override the equality to be a value equality this is going to add a bunch of boilerplate to the code but we're going to live with it because we are just building a tutorial example app however if you are building a production app you should probably not do what i'm just doing to generate equality like this i am by the way using an extension for vs code called dart data class right here from bendix ma but you should probably not do what i just did and just create a bunch of boilerplate yourself right here you should probably use something called freest which is an awesome package which has a support for unions which are basically subclasses on steroids we could say and it also adds all the needed value equality for you automatically it works by code generations and again link to it is in the written tutorial to which you can get from the link in the video description if you have not yet heard about it you actually absolutely need to override equality for your state classes because otherwise block will not emit two states which are equal after one another and if you leave in the referential equality instead of overriding it you can sometimes arrive at the situation which will be acting weird and you are not going to understand why a particular state was not emitted until you remember that oh i forgot to override equality and you're just going to waste a bunch of time so you should always override it to have a piece of mind all right the next state the last one is going to be weather error so again hit ctrl d say whether error and this one is also going to have a final string message signifying the error message and let's again add final field form parameters and generate equality using the extension so this is what we have right here for states where initial weather loading weather load did and whether error again you can get all of this code from the link in the video description so having done this let's now implement the weather qubit which will perform logic of getting the weather from the repository and then also emitting these states which we have just built this is the code already generated by the vs code extension it's basically a weather qubit which extends qubit of weather state and then it passes whether initial to be inside the superconstructor which makes it how else the initial state again initial state will tell the ui that it should display only this search bar and nothing more now as proper developers we are going to sort of prepare for dependency injection by having a field final weather repository containing the weather repository and uh we're going to sort of prepare for a constructor-wise dependency injection so basically we will need to pass a weather repository instance to the weather qubit and well then we simply want to create a method called get weather but because we are going to be operating with the repository which returns a future this must also return a future but it will be a future of void because we don't really want to return anything from here we just want to make sure that this method for getting wetter can be asynchronous it's going to accept a string city name and again a sync here just like that and what do we want to do now well at first we want to emit a state so if this is the first time that get weather is called the state is whether initial because it is said to be the initial state but then we need to emit a new state immediately that this gateway is called to indicate that the ui should display a loading indicator we can tell this to the ui by emitting the state called weather loading so let's do just that we're going to emit we're loading and that's it actually we could use the constant constructors here just for the performance benefits but actually let's not confuse ourselves here probably i'm just going to use the new keyword like that if you emit new it's new by default then of course we want to fetch the weather from the repository and we are going to put it inside a final weather let's make it equal to a weight of course weather repository fetch weather and just pass in the city name which was in turn passed into this get weather method so now that we have this weather let's think about what we should do with it right well we should emit again whether load did this time which is the state which takes in a weather instance but how are we going to handle the possible error well we know that fetchwetter can throw a network exception so we need to account for that therefore we are going to wrap this whole code block inside a try catch block so let's move this code into try and in the catch clause we're just going to say on network exception and in such case we want to emit weather error and now we're just going to hard code an error message in here i'm going to leave it up to you how you do it in your production apps you should probably think about just passing around some codes some error codes probably some integers or some constant strings which you are then going to translate in your presentation layer in your ui using your favorite localization library into some actual user readable messages but for now we're just going to hard code everything right in here and well that's really it for the get weather method and for the whole qubit as it is right so let's now move on to the user interface first up we need to make sure that this qubit is available throughout our whole ui we want to provide just one qubit instance and for that purpose we can use a block provider you are probably familiar with the provider package and block provider is built on top of that package built specifically to work with block in a completely seamless way so let's move on to the main dot dart file and since we have just one weather search page we can just wrap this with a widget called block provider let's import it from flutterblock.dart and over here we are going to say create which is going to instantiate a block or actually the weather qubit for now because as you can see we are using a block provider for a weather qubit not weather block but we can completely do that because block is built on top of qubit block in other words extends qubit so that means they are fully compatible and you can use both qubit and block with the widgets which the flutter block library provides so let's just instantiate flutter qubit but we mustn't forget that this takes in an instance of a weather repository which in our case will be the fake weather repository okay with this done we can now access the weather qubit throughout our whole weather search page so let's go over there to weather search page and let's do something about it right the startup project which you could have gotten from the written tutorial already contains pre-built methods returning widgets so we have build initial input build loading build column with data which looks something like this this is the column with data and then we also have a city input field which is a widget in itself where we need to implement the functionality of actually calling the get weather method on the qubit to start fetching the weather because all of the widgets or the methods right here are already prepared all we need to do is to just swap this hard coded build initial input which is currently always displayed in the app for a dynamically loaded ui based on the state which has been emitted from the qubit actually let me just run this app in the emulator because currently we are just running the already prepared app for when i was preparing for the recording here here we go and as you can see we can enter a city here but it's not going to do anything because all we are doing is just building initial input and we are not even calling any methods on the qubit so that's not cool let's change that we want to implement this with qubit so the way we do that is by providing a block builder right here then we need to specify as a type parameter first will be the qubit class and then the state class with which we want to operate so whether qubit is the name of the qubit and then whether state this will automatically get the qubit using the provider which we have added in main.dart you can also obtain the qubit manually if you really want to and provide it as a qubit here so just say block provider dot off context and provide weather cubit right this is the standard provider or inherited widget syntax but you do not need to do it because as i said block builder will perform this fetch automatically what we do need to specify here though is the builder method which provides us a context and a state which has just been emitted from the block or in this case from the qubit and what do we want to do here well since we have just basic subclasses in here because we are not using freezed for example which has the support of nice unions we need to just check through all of the instances of the subclasses because the state is of type weather state which is the subclass of every single state class we have built right so we're going to check if state is whether initial in that case we want to return build initial input in case that else if state is weather loading when i return build loading again else if state is whether low did we want to build return build column with data and pass in state dot weather and lastly else which in this case this means that state is whether error right let's put this into parentheses then we want to return again build initial input because in the case of an error we're just going to show a snag bar which we are not yet showing but the ui will basically look the same as if it was an initial state it was emitted but again we want to show a snag bar so how can we do that in reaction to a state change coming from the qubit well the code to showing a snag bar is very easy to write but we cannot really put it inside the block builder because then we are going to get an error message saying that set state or mark needs rebuild was called during build basically when you are building the ui you should really only build the ui return some widgets and not do anything else for example you just cannot navigate to a new page during a build and the same thing applies to snag bars which are basically also just navigating to a snag bar you can pop it it's really a route on top of your current route you just cannot show a snag bar during a build also flutter can decide to run the build method whenever it likes basically and the same goes for block builder and we definitely do not want to arrive at a situation where we show multiple snag bars because the current state of the qubit is the error state but we just show it multiple times because flutter decided to rebuild the ui for some reason of calling set state somewhere deep in the widget tree or something like that so we need to have a way to perform showing the snag bar only once per state change and also to show it in a way which is not going to cause any errors in red screen of death that's exactly why there is a block listener block listener is a simple widget looking very similar to block builder but instead of a builder it has a listener method and that's basically the only difference there and you do not return widgets from that listener method but you just perform some actions some side effects now we are now going to use a blog listener here but you definitely could block listener and basically just wrap block builder with that widget and then implement the listener method right all such things and it would be completely cool but as you can see this creates nesting and whenever you can avoid nesting you should definitely avoid it as much as you can and that's also why instead of using block listener we can merge block listener and block builder together with a block consumer which is a class which very nicely provides us the option to build and also listen to the block at the same time so let's do just that and basically here we just want to check if state state is whether error in such case we want to call scaffold off context and then we just want to show a snack bar whoops and the snack bar will be very simple nothing too fancy just a snag bar and its content will be a text and now we want to provide an error message to the user so we are going to say state which is coming from the qubit dot message like this and now lastly after we have built all this which is basically showing different widgets or a snag bar in reaction to the states coming out of qubit what we now need to do is to add the ability to trigger a state change from qubit how can we do that well we want to handle the case whenever the search button is pressed on the keyboard and then we want to call the get weather method on the qubit which is going to trigger all of the state changes and all such things so we want to add the call to getweather on the weather qubit all the way down in the weathersearchpage.dart file i have prepared a submit city name method and all we need to do here is to basically get hold of the qubit again we can do so using a block provider dot off and do it the old-fashioned way but we can also just do it in a more new way using extensions by calling context block and over here we want to provide uh weather qubit again we are calling block but it is interoperable with cubits so that's completely fine we're going to put this inside final weather qubit cool and now we just want to call weather qubit dots get wetter and pass in the city name which was passed in turn into this method in the ui awesome so now with all of these changes we can now search for a city here so i just put hello here search for it and we get an error which is nice to see actually and then some other city hopefully we are going to get successful data and we do and you can see that everything has worked successfully so this is it for the qubit part and now we are going to switch everything to block it's going to be very simple and very quick because basically most of the things which we have built can stay in here definitely the checking through states can stay in here the block listener can also stay in here and also whether state can remain completely unchanged and most of the things which are built inside qubit can remain unchanged there are going to be some really minor changes because basically the only thing which block adds on top of qubit are the events so there are not going to be a lot of changes to take care of also i am now going to commit this to say finish project qubit right commit this and you can get this qubit finish project and then also later on the block finished project from the written tutorial from the link in the video description so definitely check it out so the first thing we want to do when we are switching to block is to create a block new block again so just right click on the lib folder block new block it's again coming out from the vs code extension same thing should be available on intellij or android studio and you want to call it again weather so now what's going to happen is that we're going to have this block folder and it looks very similar to the qubit folder but we have one more file which is for the weather events like this let me actually close all of the files and let's again begin with weather state we're actually not going to do anything new here we just want to go to weather state from the qubit folder copy all of the states ctrl c and go to weather state control v or command v on mag of course and uh yeah so that's basically it we have just copied all of the states to the weather state dart file present in the block folder now we just need to import weather here like that and we are good to go now that we have states we should move over to events and we basically know what kind of an event we should have here because again events are just a more uh boilerplatey but for a good reason boilerplate as i've said you can perform even sourcing so if you want such things you should definitely use a block but anyway we know what kind of an event we want we want the get weather event which in the case of a qubit it was just a simple method so we're going to have class get weather and we will extend weather event and we're just going to have a final string city name here and let's create a constructor for it and that's it you don't actually need to override the referential equality to be a valid equality in the case of events however in the case of states this is really what you need to do so that's awesome it didn't even take much time but we have already implemented the state and event files so now we're just going to move over to weather block and implement that again it looks very very similar to qubit we again want to have weather initial to be the initial state of the block again we can actually come over to cubit and copy the weather repository dependency field and paste it into weather block because again we are going to need to have a weather repository let's import the weather repository class let's add it to the constructor and now we need to implement the map event to state method events come into the block and states come out of it in the case of qubit there are no events but only methods but still states come out of qubit as well it's just that qubit really hides the stream which is being used behind the scenes and instead of using the regular dart keywords for yielding new states from an asynchronous generator as we are gonna do in just a bit in the block you just call emit and if we take a look at it it really just uses a stream controller and adds a state to it so still there are streams being used but they are just really nicely hidden in behind the interface right behind the emit method in the case of block we don't have such emit method but instead we use an asynchronous generator and instead of calling emit we're going to call yield yield like that and yield for example we're loading okay however we cannot just do it like this because we first need to check if the event which is incoming into this method is actually the event which we expect in our case it's always going to be just the get wetter event because after all this is the only event which we have but in the case that you have multiple events you definitely want to check for their type so we're just going to say if event is get wetter and now we can basically do the same thing which we have done in weather qubit so let me just copy the try catch block from the get wetter method paste it over here and just let's select all of the emit occurrences so again ctrl d or command d change it to yield delete the first parentheses or parentheses c i'm not sure if it's uh possible to be in singular but anyway once we delete all of the parentheses here and change emit to yield and then also we need to pass in the city name to the fetch weather method on the repository but now we cannot just pass in the city name because we are not inside a method as here in the qubit we just got cname right out of the bat but in the case of a block we need to retrieve the city name from the event as a field like that so we say federer event dot city name and with these minor changes we have just successfully implemented the weather block so let's now go over to the ui and make it work with the weather block again the changes are going to be absolutely minimal the first change which we obviously need to do is to provide the weather block instead of weather qubit so let's just change the weather block import it automatically and here we go we are now providing a weather block instead of weather qubit and then the only changes which we are going to need to do here in the weather search page is to change the block consumer to work with weather block instead of weather qubit and also delete the import to weather cue bits right here so let's delete that and now we're going to get a bunch of errors here but let's import weather block this time like this and with whether block imported and this block consumer change to work with weather block let's just scroll down and let's also make sure that this submit city name will work with whether block oops with a block and again because it's a block we cannot just call getweather on it but instead we need to add an event to it which is going to be the get weather event and we need to pass in the city name just like that let's just quickly try if it works so i'm going to hot restart the app just to be safe and let's say new york search for it and here we go we can see that it works which is good to see so you have just successfully implemented the same app for the second time now with a block instead of qubit and it didn't even hurt so really you can just always start out with qubit and once you find out that oh i'm probably going to need to do some more advanced operations which only the block can do like for example tracking the events which are incoming into the block you can just switch it just like that no problem switch from qubit to block in really a matter of minutes and you're gonna be good to go to go through this tutorial again at your own pace and to get all of the code check out the written tutorial available from the link in the video description and if you are serious about becoming a great flower developer who can build real apps for clients or at a job go to flutter.education link is also in the video description by the way to get the top curated floor news and resources aimed at improving your app development career over there you can also subscribe to my mailing list to get the best floor resources delivered weekly right into your inbox and if you don't want to miss more tutorials like this regarding flutter packages state management and all such things about flutter be sure to subscribe to this channel and also join notification squad by hitting the bell button to make sure you grow your flutter skills because here on resocoder i am determined to provide you with the best tutorials and resources so that you will become an in-demand flutter developer if this video helped you with understanding the qubits and block from the blog package give it a like and also share it with our developers who are surely going to find it beneficial too leave a comment if you have anything to say and see you in the next video [Music] you
Info
Channel: Reso Coder
Views: 74,443
Rating: undefined out of 5
Keywords: resocoder, tutorial, programming, code, programming tutorial, flutter, flutter tutorial, flutter state management, flutter state management bloc, flutter state management tutorial, flutter bloc, flutter bloc pattern, flutter cubit, flutter cubit tutorial, flutter bloc library tutorial, flutter bloc vs provider, flutter state management provider, flutter state management mobx, flutter best state management, flutter best practices
Id: y564ETOCog8
Channel Id: undefined
Length: 47min 57sec (2877 seconds)
Published: Tue Aug 04 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.