#3 - Flutter BLoC Concepts - BlocProvider, BlocBuilder, BlocListener | BLoC - from Zero to Hero

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what is going on everyone i'm wikid and today it is time for me to introduce you to another important topic on this block from zero to hero tutorial series remember that in the last video we talked about the standalone block concepts like streams blocks and qubits well they will serve as the foundation to the flutter block concepts we'll cover up today so without further ado let's get right into it there are some important basic flutter concepts you really need to understand before getting our hands dirty with flutter block concepts so we'll begin with these first in order to make sure everything goes nicely into place let me start by highlighting the proverb everyone interested in flutter heard at least once everything in flutter is a widget right so smash that like button if you knew that well since in this video we'll be discussing flutter block concepts you must know that every concept is actually a widget but what exactly is a widget widgets in flutter are classes classes which have their own attributes and methods these classes can be instantiated as objects by defining their required parameters and methods into their constructor as an example let's take a look at the floating action button widget as you can see there are all sorts of parameters passed through the constructor of this widget the foreground color the background color the on press function and many many more if you tap ctrl and click on the widget vs code will open a tab which contains the floating action button widget which as i told you is actually a class with all kinds of attributes from primitive types like booleans strings doubles integers to functions and even other widgets you may have also noticed that some widgets have a child parameter well what could be that for well since everything in flutter is a widget there must be a way for the framework to keep them organized right and what's a better way to nest and organize stuff than using a tree observe this picture take a look at the top of the tree that's the root note below that you can see two other widgets emerging from it these are the children the above widget is also called the parent widget or the ancestor and that's how the tree evolves for every widget until there are no more children inside the tree now that we know what a widget is and how flutter organizes them let's start with the first flutter block concept which is block providers now a quick note so that you won't get confused remember that in the previous video i talked about qubits and blocks and the difference between them well there won't be a block provider and a separate qubit provider in this case qubit is a smaller part of a block so it works the same as a block with block provider hence every flutter block feature i will discuss today will apply to both qubits and blocks so have you ever asked yourself after you build your first block how will you access it in your ui how will you access it inside flutter in the first place you might say that you will create a block object for every widget where it may be useful if that's what you're thinking well it's actually pretty wrong i mean extremely wrong what if you have an internet block which manages the current state of the app in different network scenarios think about how many widgets should have a working instance of the internet block available so creating an instance for every widget that needs it is a terrible idea instead what you must use is the block provider widget block provider is a flatter widget which creates and provides a block to all of its children this is also known as a dependency injection widget so that a single instance of a block can be provided to multiple widgets within a subtree in other words the entire subtree will benefit from a single instance of a block injected into it hence the subtree will be dependent on the block we're providing so for example if we instantiate a block provider with a block a here at the top it will be available through the entire subtree below it if we instantiate it here in the middle part of the tree the block instance will be available only to the nodes below and to none of the ones above notice how block provider creates the single instance of the block using a function which takes the build context as an argument and returns the only one instance of block a build context is like its name is implying the context in which a specific widget is built so we'll have the current widget context and will be instantiating the block a to all of its widgets in the subtree but how can we access it in the subtree the single instance of block a can be accessed by calling blockprovider.of blockadecontext or even simpler by calling context.block of blockay an optimization technique blockprovider offers is that by default it will create the block lazily meaning that the create function will get executed when the block is looked up for via block provider of block a context so that there won't be a ton of created blocks when they're not needed inside the app to override this behavior and force the block provider's create function to be run immediately as soon as possible lazy can be set to false inside the widget's parameters take in mind that even though block provider is responsible for creating the block it will also automatically close the block so that there won't be any stream leaks all over the place okay so this is what happens locally when you have only a screen in your app but what is it going to happen where there will be a new portion of the three available to the existing one this scenario can happen when we push a new screen into the navigation routing feature of flutter is the block a going to be available there too the answer is no and that's because there is another context created on the new route a context which the block provider doesn't know yet so in order to pass the only instance of the block to the new route we will use block provider that value in which we'll pass the block a to the value parameter thus making the instance of it propagate through the next widgets note that in this case the block provider that value won't close the block automatically since we still want the block to be accessible into the ancestor tree above since we initially instantiated the block with block provider it will as i said handle the closing part automatically this was a brief introduction how block can be accessed inside flutter but we will have a separate video in which i'll talk more in depth about block access across every possible scenario now as an example to make sure you understand the block provider concept by actually practicing it we will start implementing the default counter app from flutter using block so let's start by creating a footer project you can name it whatever you want and then add the flutter underscore block dependencies into the pub pubspec.yaml file note that i'm also using the blog vs code extension so i recommend you to download it because believe me it will make your life easier along the way since the counter feature of the app we want to implement is really simple we will start by creating a new qubit called counter qubit from here i will start by coding an implementation that will be more extensive and self-explanatory instead of a quicker and abstract one i'm doing this so that you'll understand all the concepts really really well so in the folder created by qubit we'll open the counterstate.dart file and modify it so that it only includes the counter state class this class will be the blueprint for all the possible states which will be emitted by the qubit since this class must have the counter value let's write it down and also create a constructor for it the application must have a valid counter value at all times so every time we'll have a new state emerging from the qubit the counter value must be a required attribute hence annotating it with the required keyword now inside the counter qubit file firstly we need to set the initial state of the counter qubit can you think about what the initial state is well it is definitely going to be a state so we'll select the counter state class then as you can see we'll receive an error inside vs code telling us that the counter value parameter is required so we need to pass it inside the constructor the initial state of the counter app will have the zero value so we'll set the counter value to zero then all we have to do is implement the increment and decrement functions which will emit new counter states so the increment function will emit a new counter state with a new counter value passed into its constructor a counter value which is going to be equal to the current counter value plus 1. you can access the current state of a qubit by using the state keyword this will return an instance of the current state of our counter and by saying state.counter value will receive the counter value of our current counter state the same procedure applies to the decrement function the only difference being that instead of adding one we'll subtract one from the current counter value okay so we finally created the counter qubit successfully by using everything we learned in the previous tutorial now it's time to link the qubit to the ui using the first concept we learned today the block provider as you can see in the main.dart file the top of the tree is actually the material app widget this is where the tree starts from in most of the folder apps so from what we've learned today in order to make our counter qubit available throughout the entire tree of our app we must create a block provider with it at our material app level so all we have to do is select the material app and then click control plus period to open up this dialog and then select wrap with block provider i told you the block vs code extension will come in handy then into the create parameter all we need to do is to take the current context and return a counter qubit instance make sure you also import the flutter underscore block up there into the import section okay so what we did now is we told flutter to create a single and unique instance of the counter qubit and make it available to the subtree below material app widget onto our home page we will adapt the code a little bit by adding a row child to the column widget a row which will contain two children the two floating action buttons which are supposed to increment or decrement the counter remember what i said when we started learning block that for every interaction an user makes with the app there should be a state emerging from the app letting the user know what's going on having that in mind we conclude that for every tap of either of these two buttons there should be a new counter state perhaps counter value shown on the screen to do that we need to call the increment or decrement functions on the qubit instance but how do we access the instance of the qubit as i told you before either by calling block provider of counter qubit context or with context.block of counter qubit then all we have to do is to pass the increment slash decrement functions onto the on press parameter on the floating action buttons which tells us that every time we press one of these buttons the qubit.increment or decrement functions will be called adding or subtracting one to the current state the question now is how do we receive the new state inside the ui how do we rebuild the specific text widget which prints out the counter value it is now time to introduce the second important flutter block concept which is block builder block builder is as its name suggests a widget which helps rebuilding the ui based on some block state changes this is the magic component which rebuild the ui every single time a new state is emitted by either block or cubic if you watched my previous video on block concepts you have to know that this block builder is actually you waiting for the boats your friend sent down the river you are the block builder waiting for the boat and its number so that you can rebuild the ui by calling the number out loud now you have to understand that rebuilding a large chunk of the ui inside your app may take a lot of time to compute so that's why a good practice would be to wrap the exact part of the ui you want to rebuild inside block builder for example if you have a text widget which updates from a sequence of emitted states and that text is inside a tone of columns rows and other widgets it is a huge mistake to rebuild all of them just to update the text widget instead what you should do is rebuild only the text widget by wrapping it inside blog builder syntax wise blog builder is a widget which requires a block or qubit and the builder function the builder function will potentially be called many times due to how flutter engine works behind the scenes and should be a pure function that returns a widget in response to a state so what is a pure function you may ask well a function where the return value depends only on the function's arguments and no others thus making it pure so in this case our builder function should return a widget which only depends on the context and state parameters and nothing more if the qubit or block is not provided the block builder will automatically perform a lookup for its instance using block provider and the current build context now for even more control of when should the block builder rebuild the ui there is another parameter which you can use called build when this should take in a function having the previous state and the current state as parameters for example if the current state contains a text value and that text value is greater than the previous state text value you can return false so that the builder function won't trigger and won't rebuild the ui okay so it is now time to integrate block builder with our counter app example we left the app open inside the main.dart file the counter value of the app should be printed right inside this text widget right here now all we have to do is to wrap this specific text widget into a block builder by clicking control plus period and selecting block builder note that i could have wrapped the entire center widget with a block builder instead but that would be wrong performance wise since the builder function will rebuild the entire widget tree instead of only the specific part we're interested in which is the text value okay so now into the builder function for every new emitted counter state the text widget will show a new value the value can be accessed by calling state not counter value and then by converting it to a string since we know that the value is actually an integer it is finally time to test out our app a moment which we've been waiting for so long so let's run it together as you can see when i'm pressing the plus button the counter qubit calculates the new counter value emits a new counter state with the new counter value and then ui rebuilds with that specific value to make this rebuilding process even more clear take a look at how i can play with the emitted states i can check whether the state that counter value is negative and print a negative text widget i can check if the counter value is even and print yay or i can check if the counter value is equal to 5 and print number 5 into the ui i hope you can now understand the power of streams states and block it may seem like block is a little overkill for a counter app but in order to understand the concepts we need to try them on simple examples and then see the power of it and what amazing apps and features you can build by using it i hope you understood the block builder concept because it's now time to move on to another flutter block concept which is block listener block listener has mainly the same structure as block builder but it is really different in many ways you see the block builder function can be called multiple times inside the flutter engine due to how flutter engine works behind the scenes so for example navigating to another screen can't be done inside block builder as a response to a state change because this action can be actually done multiple times imagine the builder function inside being called five times would you want the new screen to be pushed inside the navigation stack five times no way or what if you want to show a snack bar or a dialogue for a new arriving state the builder function may be called 4 times by the flutter engine rebuilding the ui accordingly but the snag bar will be shown 4 times as well as the dialog box which pretty much is not what we want this is where block listener comes into place as its name suggests this is a flutter widget which listens to any state change as block builder does but instead of rebuilding a widget as block builder did with the builder function it takes a simple void function called listener which is called only once per state not including the initial state again for fine grain control there is also a listen when parameter function you can pass to tell the block listener when to call the listener function or not as build when parameter was for the block builder widget to understand block listener easily what we want to do is the following every time the user presses plus or minus buttons there should be a snack bar showing in the bottom part of the screen saying incremented or decremented depending of course on which button was pressed can you guess how we're going to do that let's start with the beginning so what happens when we press either of these two buttons the increment or decrement function from inside the qubit gets called what do these functions do well they emit a new counter state with a new increment or decremented counter value so this is mainly where flutter understands what the press button does and this is where we should tell flutters ui to a state that we incremented or decremented the value so all we have to do is to add another boolean attribute to the counter state class calling it was incremented this was incremented field will be true when we press the plus button and false when we press the minus button we can go into the counter qubit class and modify the increment or decrement function accordingly setting up the was incremented parameter as we discussed and now we can go back inside our block listener and based on our state's was incremented attribute we will display a snag bar accordingly to whether the counter value of our counter state was incremented or decremented and voila you can see from the screen that our application works as we wanted so perhaps you're in our situation right now when you're updating the ui using blog builder and also showing a snack bar using block listener isn't there an easier way to do it of course there is it's called block consumer block consumer is a widget which combines both block listener and block builder into a single widget how convenient so instead of writing block listener on top of block builder as we did in our example actually we can refactor the code by writing both of them inside the block consumer widget and then copy and paste the necessary content from block listener to the listener function and the content from block builder to the builder function and voila the code is now more readable and easier to maintain and the application works perfect another amazing flutter block concept which you'll use a lot is repository provider repository provider is the same exact widget as a block provider the only difference being that it provides a single repository class instance instead of a single block instance we will talk about repository more thoroughly in future tutorials when i'll introduce you to the block architecture in a couple of words a repository is a class which has the main functions which make flutter communicate with the outer data layer the internet the apis the databases and so on and so forth again we'll cover these concepts in depth in future tutorials in more future rich applications you can imagine that there will be maybe tens of blocks and qubits having their own functionality in this tutorial we talked about how we can provide only one block or qubit to dui but what are we going to do when we have 10 blocks to provide and 10 blocks to listen to when we want to display 10 different snag bars we will stack them together one after another no we will definitely use multi-block provider multi-block listener and even multi-repository provider so these are mainly the simple concept widgets we discussed before but instead of taking only one block or qubit or even repository they can take as many as they possibly can okay so it is finally time to wrap things up if it's the first time you solve this concept this might be a pretty difficult tutorial and i recommend you to watch this video at least twice and then try to build this counter app by yourself so that you can understand the flutter block concepts by practicing instead of just watching the tutorial however in the next tutorial we'll dive into block architecture and how easier it will be for us to organize and maintain every app until then take care stay safe this was wicked from flutterley and i'm out
Info
Channel: Flutterly
Views: 41,402
Rating: undefined out of 5
Keywords:
Id: NqUx-NfTts4
Channel Id: undefined
Length: 24min 37sec (1477 seconds)
Published: Sat Sep 12 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.