Flutter bloc library basics - Felix Angelov

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
okay let's get into it um our first speaker i'd like to welcome today is felix engelov felix is a senior software engineer at very good ventures and the creator of the block library which is a flutter favorite uh today felix will be giving a talk on the block light on block library basics so uh take it away felix everyone thanks so much uh for that intro and thanks for having me um it's awesome to be here so let me share my screen and hopefully everyone can see that so um yeah the the plan today was just to go over some basics for uh people who might not necessarily have used the block library before or maybe are just getting their feet wet and trying out different state management solutions so um yeah let's just jump right in um yeah for those of you who don't know me on felix i work at very good ventures where we do flutter development of all kinds we do things from building apps for companies and training in flutter as well as team augmentation and other things so if you're interested in learning more about very good ventures you can check out um you can check them out at very good.ventures and for today's talk i wanted to go over kind of like high level goals of the block library and package ecosystem introduce the two core concepts qubit and block kind of compare and contrast them and then end off with some live coding so let's just jump right in um of course i wanted to kind of talk about like uh why you might care about some of this stuff like you might be wondering why don't i just use that state for everything and you probably could for a lot of things um but one of the main goals of the block library is to help you decouple your business logic from the presentation so you can develop the logic in parallel with the ui in some cases you can reuse logic in other parts of your app and even share blocks or qubits across multiple applications we also try to make state changes predictable so when you use the library uh you should the goal is to always know like how did my app get in the state uh what events led to uh the state that i'm currently in be able to do cool things like replay states track uh state changes and have like really detailed logs so just making the whole experience of developing and using the app very predictable we also have emphasis on improving testability and simplifying testing so there's some helper libraries and tooling to help make testing easier and as i mentioned facilitating code reuse so originally the block pattern itself um that like was originated in google i think in the ads team the whole goal was to share dart code and business logic between angular dart and flutter so again like it's pure dark code so you should be able to reuse it across multiple applications and even like create packages and even publish them on pub.dev so uh being flexible and reusable is a huge advantage and one of the simplest and like core concepts is this thing called qubit which is actually somewhat new uh before it was just this block class that you got from the block package but after seeing um how it was being used across the community and speaking with many members of the community this concept of cubit kind of arose organically and basically you can think of a cubit as a very simple dart class which the ui can call functions that are defined in that cube of it and then that qubit can do some processing have some logic execute and then it emits some states back to the ui asynchronously so it's kind of like if you were to ask your friend like hey can you go check the weather for me and then your friend goes on their phone or however they want to do figure out what the weather is and then later they tell you what the weather is so you're directly asking directly communicating via these function calls so that's a huge distinction between block which we'll get to in a second uh don't worry too much about the details of this slide but the main thing i wanted to call out is the surface area of the api for qubit is fairly small so like the main thing that you really have to keep in mind when you're using it is um using this emit function um to update the internal state of the qubit so for example you can define a function called like request weather or fetch weather or whatever it might be have your logic for figuring out what the weather is and then you would call emit with the updated weather and whoever is listening for changes on that weather state would get notified so pretty much a very simple and minimal api surface which makes it easy to use for beginners and simple use cases and so to jump into some of the code if you're wondering what it might look like in the simplest case which you probably all have seen with the counter app that you get out of the box when you run flutter create we can manage the state of that counter with a qubit um by importing it from the block package and we can define our counter qubit class which extends the qubit class from the block package and then you have to define what kind of state are you going to be managing so in this case you could just define it as an integer this could be a complex state like some sort of custom class it could be an enum it could be a string it could be whatever you want and then you have to define what the initial state is going to be so the state before anyone has interacted with the qubit in this case we can initialize the counter to zero and then you can define as i mentioned the previous slide any number of custom public methods that the ui can call and then internally use this emit method to basically update the state of the qubit so very similar to some other approaches and a very simple api so um yeah you can pretty much get very far with very little code which is one of the advantages of using qubit um and now let's i just want to contrast with block so a block was kind of like the first thing um that uh kind of like sparked the creation of this package and it's very similar to cubit i like to think of a qubit as a stripped down block so i like to think of cubit as block if you remove the concept of events and so going back to the analogy before of like i want to know the weather so i asked my friend directly hey can you tell me what the weather is uh that would be the cubic case whereas the block case might be more similar to me sending my friend an email or messaging them on slack and having some kind of like level of or layer of interaction between uh the actual interaction of me and and my friends so i'm never directly communicating with them i'm notifying them somewhat asynchronously and indirectly and so that's kind of the key difference the ui ads events or notifies the block via events as opposed to calling methods directly and that gives you a lot of flexibility in terms of like the blocking control how these events are processed how frequently they're processed in what order they're processed etc um so you can take advantage of some powerful rx operators like buffering debouncing switch mapping etc um don't worry about it if you don't know what those are it's just for advanced use cases you have that flexibility with clock but again the same thing with blocking qubit is like you're just admitting states to the ui and the ui is just listening to any updates so the api is a little more complicated but it also gives you some more flexibility in terms of processing events and processing how those events are converted to states and in what order etc as i mentioned so you can see all of these diagrams at blocklibrary.dev if you're curious and you want to check it out later it kind of breaks down each of these apis and what it would be used for and how it might be helpful in certain situations and uh to circle all the way back to what the code would look like um very similar to the qubit example except for we have to define what types of events this block would be processing so instead of defining functions you define events in this case i'm just using an enum but you can also define classes um whatever whatever you want to represent the types of events that the block can react to similar to the qubit we have to specify what the initial or starting state is going to be so again zero and then again rather than defining custom functions you override this method called map event to state which is kind of like the inbox of your your friend or whatever in that analogy so every time someone asks for something uh you get it in this map event estate function and then you have to reply to it asynchronously and you reply using like this yield keyword so this whole function is an async generator meaning it emits a stream of states and you can use the yield keyword to pump new states out so whoever is listening will receive them and juxtaposing everything side by side just so that you can see them everything is very similar again the key difference being qubit uses functions that the ui calls directly whereas the block uses events the api surface is smaller and simpler and you end up writing less code which is good whenever you don't need extra code it's great to not have to write it and overall they both have their advantages and disadvantages um i highly recommend using qubit if you're not sure which one to use and you're using the block package because you can always scale up to block as needed uh and refactor your qubits and convert them to blocks but there are cases for example if you're building like some sort of search functionality and you need to process and and deep balance events and things like that where block becomes a bit more useful and could come in handy in those cases and qubit is kind of more for those simpler states that you want to manage so both of them are easy to test they both integrate well with all the other block library packages they're both scalable you can have hundreds of them in your application and you can even have a combination of qubits and blocks in the same project so you don't have to feel like i have to choose just one or the other um and they both have support for the vs code and intellij plugins and extensions so you can kind of like pick and choose which one makes sense for this use case and then as always you can upgrade from qubit to block if you find out that i actually need the more advanced functionality and power of the api and so now in the remaining time i'll just try to go over some like live coding of what this might look like in vs code and i'll pull up this simulator over here so um basically what i've done here is i've just like stripped down the app that you get when you run flutter create so i'm importing the floater material package running this to my app widget which is just a stateless widget that's rendering a material app because i just want to use the material theming for this case and i have a page called this counter page which is just a scaffold with an app bar a floating action button here that i can click and then a text widget which has just a hard coded value of zero and so i kind of want to just walk through now how we would take something like this which is not really functional there's no logic and how you can make this functional add some business logic using first qubit and then refactor to block so the first thing i'm gonna do is come over to the pub spec and i'm going to add the flutter block package and get the dependencies and um the flutter block package automatically exports the block package so if you're using flutter you don't need to import both you can use just the block package if you want to have just a pure dart experience developing there's also an angular dart or an angular block package if you want to use angulardart etc so you can check out the documentation for more information and i'm going to do this in line but you can also take advantage of if you have vs code or android studio you can install the block plugin or extension and it will give you some cool functionality like i can right click and create a new block or a new cubit give it a name and the tooling will generate the code for me in this case i'm going to do it in line so that everyone can easily see and follow along and i'm going to use the vs code snippets which are also part of the extension but typically you might want to like separate the qubits or blocks from your widget just for organizational purposes so just keep that in mind so i'm going to use the snippets as i mentioned so i can just type the word qubit and then i'm going to just name it counter cubit as we saw in the slides we need to give it the type of state and i need to import it and then i need to initialize the initial state so i'm going to set it to zero and in this case like everything's happy there's no complication errors this is just the minimum that i need to do uh to define a qubit and this one has no public api now so i can't actually interact with it so i'm going to leave it like that for now and the next thing i want to do is actually provide this qubit to the widget tree so that it can be accessed and someone can interact with it and react to the state so the way i'm going to do that is again i'm going to use the vs code extension and you can click on this light bulb or command dot control dot and wrap with block provider and block provider is a widget from the flutter block package which uses the provider package internally and it basically just provides the instance of the blocker qubit to the subtree so in this case i can provide an instance of this counter qubit to the counter page and its children and in this case we don't need context so i'll rename it and so now this counter page can access this counter qubit via the build context and so in order to do that i'm going to use a widget called block builder which is kind of similar to stream builder if you're familiar with using streams in flutter so i'm just going to wrap this text widget because this is the only widget that actually cares about rebuilding in response to the state changes so here i'm going to say i'm going to react to state changes in this counter qubit those states are going to be of type integer and now i have access to that state in the builder method so i can just replace that hard-coded counter or how hardcoded zero with the state and i can save hot restart nothing changes but it's good because now i'm no longer hard coding the zero so i can yeah restart everything still happy but now we need to do the actual interaction um so that we can update this state so we need to go back up and define a function that we're going to be calling so in this case i'm just going to call it increment and in your qubits and blocks you have access to the current state just via the state getter so i can access the current state and add one to it and then emit that whole thing and so now i have this public increment function that can be called and the way i'll call it is whenever someone presses on this floating action button i can access um i'll first do it the traditional way so you can access it using blockprovider.of passing the type passing the context and then now i can call increment so now anytime anyone taps on this button we do a lookup of the counter qubit using the build context and then we invoke the increment function so now i should be able to increment the counter there are some handy extensions so we can make this a little more concise by using context.read it's equivalent to blockprovider.of so everything still works properly and um yeah so everything is functioning we're reacting to state changes again the flow is as a user i tap the button the button uh tap calls this increment method on the qubit the cubit changes its state and emits that new state then whoever is listening to it in this case this block builder gets notified with the new state and then the ui gets rebuilt that's within that block builder so um so far so good now let's take a look at how you can let's say you start off with qubit everything's great and then you realize like oh my requirements changed and it'll be a lot easier for me to use block how can i refactor the qubit to use block so the first thing is i'm just going to select all instances of counter qubit and rename them to counter block i'm going to define the event that we're going to be or the events that we're going to be handling so in this case just the increment but we can easily add a decrement later or whatever other types of events and then now instead of extending qubit i'm going to extend block and pass the event type counter event and now instead of having an increment function i'm going to comment that out and i'm going to override map event to state i'll add this async star to denote that it's an async generator so i can use the yield keyword and then now here i can use a switch statement because this is an enum and i can basically say for the case where the it's a counter event oops counter event increment then i can use the yield keyword and push out a new state and break and so now the block is done so we've converted the qubit to the block the block provider still works we don't really have to change anything there the block builder still works the only thing now that's really an issue is there's no more increment method so we can't actually call increment directly instead we can use the add api and add the event that we want the block to respond to and now i should have everything working just like before so we've refactored from qubit to block um one other thing i want to mention for people who might already be familiar and have used library there's some changes that came out in the most recent versions of 6.1 that kind of leverage existing extensions that the provider library has so for example i can and typically you want to decompose your widget tree as much as possible to make it easier to read and a bit more organized so in this case i can remove this block builder widget here and let's say i want to just call it my counter text widget and then i can define that down here i can just copy the code that i had before put a return take my theme look up move it down and we've refactored so that we can decompose this counter page widget into smaller widgets and this countertext is the only thing that's concerned with rebuilding in response to this block state so everything should still work but now that we have the situation where we've decomposed further we can take advantage of the context.watch extension so i can actually say final count equals context.watch and pass the block or qubit that i want to react to and access the state and now with context.watch i can just return the text without needing a block builder because context.watch will basically say hey anytime the counter block state changes rebuild me and me as like whatever widget we're in uh who's build context we've used and so i should be able to save this and everything continues to work just like before i mean there are a few gotchas with this approach because you might kind of be tempted to do this up here for example and then just directly access count inside of the text widget here so if we did something like this that would work except for it's not necessarily what you want because by doing this context that watch within the counter page we would be rebuilding the scaffold the app bar the floating action button and potentially lots of other widgets that don't necessarily need to change just because uh the state has changed so it's best to try to scope this as low as possible so that only the widgets for the subtree that needs to change gets rebuilt you can still do it in line by using like a builder widget in this case so if you want to achieve a similar effect to the inline block builder you can still use the builder widget that comes with flutter let me just do this and again you can basically now do the context.watch within the builder and again since we're using the builder's context now the builder is going to be the only widget that rebuilds whenever the block state changes so i'm not rebuilding the entire scaffold including the app bar and forwarding action button etc so these are just a bunch of um convenience sticks there are a bunch of convenience extensions there's another one called context.select which i'll leave to you to go check out the documentation and mess around with if you're already familiar with provider and use provider in previous projects it'll probably be natural to you and you already be familiar with how to use it um but yeah that's kind of just a quick overview of how you could pull in the block library into your packet into your existing app how you can use it to manage state how you can scale from qubit to block and then a quick preview into how you can use some of the convenience extensions like context.read and context.watch to reduce the amount of code you have to write so that's all i've got i will stop actually let me go back i think i have one more slide so thank you everyone again for having me and if you're interested in learning more you can follow me on twitter or check out my github and yeah it was a pleasure being on so thanks again okay thank you thank you felix uh we've got a few questions to to ask you um so um first question most popular one is cupid is a light version of block is there any plans to make blocks simpler whilst keeping its features for now no i mean i'd be curious to learn more about what specifically people would like to be made simpler i think part of the reason why cuba even exists was to address that concern so yeah i think for now the plan is to kind of keep them as kind of partners in crime so you can use one for simpler cases and scale up to the other when you need more complex manipulation of streams and kind of take advantage of more like rx operations and things like that but yeah for now no but i would love to hear more about what specifically whoever asked had in mind and potentially we can simplify it i mean i'm all for simplifying things whenever possible i think it's always just a trade-off in making sure that we still have the same functionality and potentially don't introduce too many breaking changes but um yeah again i would love to hear more and have a discussion about that also you can feel free to open any issues on the library as well for whoever wrote this um i'm always like checking the issues and and having discussions and trying to figure out how we can continue to improve things so yeah definitely feel free to open up an issue if you have any suggestions okay um what are the pros and cons of different state management solutions um i think it all comes down to personal preference and what you're familiar with i think most state management solutions kind of have the same ideology and even look very similar these days so i think the biggest thing is just use whatever you're comfortable with you and your team are comfortable with and make sure that it satisfies your needs so uh there there are obviously like little things that you kind of trade off between different state management solutions like for example block is great if you love streams and you're familiar with streams and maybe you're integrating with firebase and you're directly consuming lots of streams in your application because inherently everything is a stream with blocks and qubits whereas you might want to use like change notifiers and value notifiers for other simpler use cases you might want to use mobx if you are familiar with modbx from like javascript or redux that you're familiar from um with like react um so i think like there's no really like wrong and right i think it's more just kind of figure out what feels right and what feels comfortable for your team and maybe the project size and then also don't be afraid to change like actually before um at bmw when we created the block library on my team before that we were using redux and we started off using redux then we tried using scope model and so like we had this kind of like progression throughout multiple different types of state management and we took things that we liked we took uh things that we didn't like and we weren't afraid to change our minds and refactor things as we went along so i guess another thing i'd say is like don't feel like you're locked in once you make the decision always have that like um in the back of your head that you can change your mind if you're not happy and um i think i'm a firm believer like if you architect the app properly you should be able to swap out things fairly easily granted state management is like a pretty big part of apps but still it shouldn't be the end of the world if you want to change your mind if you find out that you've hit a limitation but i think a lot of the popular ones kind of can solve most of the problems very easily and yeah i'd say just go with the one that you're most comfortable with at this point so that would be my my two cents okay um is it possible to call two methods in a block listener i'm not sure what what that is but so for those of you who don't know block listener is just another another widget from the flutter block package and it's kind of equivalent to block builder except for instead of returning widgets in response to states you can do kind of side effect things like navigate somewhere show a dialogue show a snack bar etc so you can definitely do as many things as you want within the listen listener call back from block listener like you can add an event to a different block and show a snack bar or show a dialogue so i'm not sure exactly what this person means but you should feel free to do it as much as you want in there as long as you're not returning widgets uh because that's what you would use block builder for okay are there any disadvantages of using flutter block library i think the main the main one is if you're not familiar with streams or you're uncomfortable with like the async generators and and making sure that you understand kind of like the flow of data um that's kind of like the big hurdle that a lot of people run into when they use it and a lot of the feedback that we've gotten which is why qubit exists to try to like reduce that kind of learning curve and help make it easier for newer developers um other than that i think um just potentially boilerplate i think a lot of people complain like oh i have to define classes for states i have to define classes for events it ends up being more code overall than if i were to use provider or like vanilla provider and change notifier or mobx or or whatever the case might be so if you're really sensitive to the amount of code that you're writing and you hate writing a lot of code even though i don't think technically it's that much code but i'm biased so if you prefer having like super concise and simple um implementations of things then maybe it's not for you i think that a large part of it though is to assist with the predictability and reproducibility of your state so i haven't demoed it here or talked about it but you can actually observe and tap into all the state changes in your application using this thing called block observer and so that comes in real handy for larger apps where you actually want to have like detailed developer logs uh for like what the user did how they got to make maybe like a crash or or a bug that occurred and being able to replay those so there is a reason for the code it's not i don't think that it's just boilerplate just for the sake of being boilerplate but it definitely isn't the most concise state management solution out there so uh maybe it's not for you just because you want to write less codes i think those are the two main disadvantages in my opinion but again i'm biased so and uh the last question and uh please feel free to plug plug it uh you're the editor of flutter complete reference book can you tell us a bit about this book and um who's the target audience yeah so i won't take too much credit because uh to be fair i've only really reviewed the block sections of that book but it's a great book i've read the whole thing it's targeted towards anyone who's interested in learning flutter and wants to get the most up-to-date experience the book tried to cover as much as possible even going as far as to try to cover null safety before it was out so um it's we were very mindful of trying to keep it yeah there we go keep it as uh relevant as possible even though books get outdated very quickly but it covers a large array of topics and is more geared for like practical development so less theory and more concrete examples of things it covers state management in there including provider block and some other options it covers testing it covers um ui it covers pretty much everything you need to do you need to know so it's like a really good reference to just have by you if you're if you're picking up flutter or even if you just want to go more in depth into any particular area if you're not familiar with like animations for example and you want to learn more it's a great reference and there's also an ebook version so if you want to buy the ebook version it's a little cheaper and you can have it just digitally so yeah i highly recommend it and um yeah if you have any feedback feel free to let us know um there's also a cool quiz to go along with it so you can take the quiz on the website and see how much uh flutter and dart you you know from the start and hopefully the book will help you get a perfect score by the end if you don't already have one so yeah great question okay about that book sure uh so i'm a huge fan right i mean and i've uh i bought the uh ebook version but um i've seen somebody with a printed version which looks like a modern-day phone book um i mean it's an impressive amount of coverage right i was yeah there it is right there uh i was uh super impressed to see the 200 pages up front for dart that's all that's always a sticking point right how do you get you know dart how do you first learn dart you know in a modern version there aren't a lot of dart books so that was a fantastic edition um but of course you know we just released the the beta of male safety yesterday right um and uh as uh as good as you guys are i assume there are differences do you plan to make that you know things over time right do you plan to keep the book updated yes that is definitely the goal um i think alberto who's the author of the book his intention was to have the ebook be updated regularly with major releases to dart and flutter so yeah that is 100 like one of the main reasons why there is an e-book to begin with so that we can be flexible and push those updates i'm not sure what the timeline will be for those changes since the flutter team and dart team do move pretty quickly um and writing a book does take a lot of time but um yeah that is definitely the goal so i will i can let you know once i have more information about the timeline for that if you're curious but that is definitely the goal well i have to tell you that writing just writing those release blog posts takes a long time because oh yeah yeah one of them is more and more features it's kind of uh it's become kind of a a running joke inside the team how big those cameras are getting just to keep up yeah yeah exactly yeah it's it's always been a challenge just like figuring out how to write content that's not boring also practical and um yeah making sure that it's kind of up to date no typos no grammar errors and things like that so yeah it's definitely a challenge and i i mean i'm not going to take credit for that book was basically written entirely by most of the other folks on the team i was just editing the block sections so i don't want to give the false impression that i wrote the entire book or large part of the book i was mostly just editing it so huge props and shout out to the other folks on there because they did an awesome job and it was super quick relatively speaking how fast that book was created and uh got to people's hands basically like even the shipping of the book was pretty quick so yeah that's off to all to them so yeah but i'll definitely um i'll i'll keep you posted on how quickly those updates will happen because i have been in close contact with the author so i'll try to figure out when what the plan is for the next update to the book once null safety is unstable hopefully we'll have an update shortly after well and if there's something i can do to help too if there's some kind of way i can yeah yeah definitely i'll let you know yeah thanks for offering cool totally absolutely thanks guys that was uh that was really great and thanks felix for your for your time your knowledge uh we'll be posting links to the videos um later on and also make sure we include a link to that book as well so if you want to get yourself a copy you'll be able to do so
Info
Channel: Brisbane Mobile App Developers
Views: 5,689
Rating: 5 out of 5
Keywords: flutter, bloc, bloc tutorial
Id: nc55gOsL8lc
Channel Id: undefined
Length: 32min 5sec (1925 seconds)
Published: Fri Nov 20 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.