Freezed ❄ – Data Class & Union in One Dart Package

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

yet another great resoCoder video ! thanks

👍︎︎ 2 👤︎︎ u/rxlabz 📅︎︎ Feb 11 2020 🗫︎ replies
Captions
how would you like it if dart had data classes and sealed classes just as we know them from Kotlin it would be perfect but while these features are being worked on by the official dart team they are still in the distant future now we have the next best thing though we are all about to get freezed or frozen with the new package by Remy OS la the creator of provider and also flutter hooks hello welcome to resew code room where you are getting prepared for real app development so that you will get freelance clients or a job and be confident about the apps you built so subscribe and hit the bell to join us in our quest for becoming in demand flutter developers if you've been following the darts algebraic data types in for a while you may be wondering like we have sealed unions we have super enum we have some types so why do we need yet another package and similarly if you are an avid follower of the data class scene you may know about build value equate able and there are even some certain vs code extensions which provides simple functionality to generate code for beta classes so again why do we need yet another package well I could talk for quite some time about the insufficiencies of all of the individual packages they're either too verbose there is a lot of boilerplate in other words they are too restrictive or they are just plain not cool to use and that is in itself a very valid reason to switch to freezed because it has a success and elegant syntax and using it is really a breeze but if you are still not convinced think about it we have separate packages for unions and we have separate packages for data class like functionality for example you can use something like super enum for unions and then built value for data classes so you have two packages for two things right but freest is a combined package so to say it provides elegant and nice syntax for both unions and data classes just from one import right here and actually you are not even going to import it because it's just as a def dependency free is just generates code there are no actual dependencies or import statements for freezed inside your code base so let's set up the project we are going to demonstrate this freest package on a dart castle application but also this of course works with flutter the main important thing we have in the pub spec yamo file which you can by the way get from the link in the video description and from that link you can also get to the written tutorial where you can also find all of the code written in this video links to all of the libraries and overall go through this lesson at your own pace so whether you copy this pub spec demo file from the written tutorial or not we have priest as a dev dependency build runner of course because we are going to be generating some code and then we are also using JSON and notation and JSON serializable these are not actually required by priest but the cool thing about priest is that it is very tightly and nicely integrated with JSON serializable so even converting to and from JSON will be a breeze with priests so that's why we are important you don't actually need them if you don't wanna convert to JSON and lastly we also have meta this is something which is only needed in console application because the meta package is automatically imported if you are using flutter so you flutter laughs you don't need to import meta at all once we have these dependencies and we have round the pub cat command let's get down to coding at first we are going to create a data class if you are not familiar with what a data class is it's simply a class which supports new equality that is unlike with regular darts classes so for example if I create a class right here and it has a field final index and of course we need to create a constructor for it actually we can just assign it right here it doesn't matter so it's kind of obvious that instantiating some class here and checking if it is equal to another instance of some class it should be equal if there is value equality comparison because the class still holds just X is equal to one both of those instances hold the same value but because dart is utilizing reference equality by default when we print this equality check what's gonna happen is that we're going to see false as the output and that's not what we want with data classes because data class is should have value equality and of course we can override the equals operator ourselves and do all kinds of crap but why create all of that additional work when we can just use the package such as freezed also data classes usually have a copy with method and again you can use something like the dart data class extension at least here in vs code you can use something like this and just hit ctrl + dot and generate copy wave generate equality but again it's just going to add a bunch of code into your regular file so I think that's not the best option so we are so far missing valley quality copy with for creating new instances with just minor field value changes and then data classes should also possibly have support for serialization and as I said freezed has a very nice support because it works nicely with JSON serializable and I know that not all of you are Catalan developers but just in case you are this is how you can create data classes in Catalan of course the syntax is not valid in Dart but in Catalan is literally a one-liner we can have a data class user with a name field or property because everything is a property in cousin and then we also have an H property and that's it this has overridden two string method copy with it has value equality all of that is right inside that data class which is defined as just a single line so can we get to something like this this beautiful one-liner with cotton and freezed of course we can let's create a new file under lip it's going to be called freeze classes dart and inside of it we are going to create an abstract class user it's going to be mixed in with user so underscore dollar sign user is the name of the abstract class which is going to be generated and also mixed in as you know you cannot really avoid boilerplate with cogeneration libraries but I think this boilerplate is pretty minimal and straightforward so it's a good trade-off especially with compared with the boilerplate which you would need if you were to implement all of the data class functionality manually so once we have this abstract class user the way we can create something similar to the Catlins data class which has a main property and an H property is to create a contactor E user and it's going to accept string name in H and it's going to be redirected to generate it constructor for underscore user class so this is pretty much all the boilerplate we need we of course need to mark it as immutable this is actually how the Freese backage recognizes for which class to generate an implementation so let's import the meta dart and additionally we are also going to provide a part because the generated file should be called freest classes that frees the dot you may be used to specifying G but for freest you need to specify freezed that dart okay so let's roll with this we are going to open up the console run our favorite command fluttery problem we'll run a watch and also don't forget to add delete conflicting outputs just to be safe and there we go we have just generated a phrase that dart file with all of the implementation nicely there for us and once we delete the of course invalid codling class we don't have any errors in our project and let's hop into main the dart and let's utilize and instantiate this data class so we can create a final user which is going to be equal to user and we can just instantiate it as usual we are going to pass in a string name and in H so for example Matz and twenty cool then it's immutable so we cannot possibly for example reassign age that's a good thing we can have to reassign and getter then we can also use the copy with method so final user 2 is equal to user dot copy with and we can for example change the name from Matt to John awesome so now we can for example print user and print user 2 and it's not going to print us an instance of user as usual with dart classes but it is instead going to print us a nicely formatted string because if we take a look at the generated file even that to string method is overridden and that's a nice thing to see and lastly if we just duplicate myself here so we are gonna have two users which are holding the same values inside of them and we print user is equal to user 2 we are going to get true printed out that's also good we have just implemented value equality with religious a few lines of code right here so we have all of the things we came here for and additionally let me show you that you do not have to use only positional arguments here you can also use optional arguments something like this and now you do not need to pass in H but it's going to be null by default and now actually when we run this code is going to print out false because these two objects are no longer equal even with value equality and then you can also have named optional argument so when you do something like this you have to specify it as H it's 20 just as usual this is really it for data classes before jumping on to unions or otherwise known as sealed classes let me also show you how you can work with JSON serializable in freezed so let's just revert back to positional arguments right here working with JSON serializable is absolutely simple all you need to do is to provide another part statement this one will be that G dot dart because JSON serializable Skol will be generated into a separate file from the frist generated file then we just need to specify factory and if you are used to json serializable you know all of this stuff this factory will be for user that from json it's going to accept map string dynamic let's call it json and we're going to have an arrow function instantiating user from json whoops and passing the json this is the standard boilerplate for json serializable the difference is here that we don't actually need to specify the two json method ourselves and we also do not need to annotate it with add json serializable although while we do not need to annotate it we still need to import JSON a notation because this json annotation import will be needed in the generated file so just make sure that this JSON annotation is indeed imported in your manually written file and now when we save this file all of this stuff will get generated we can see that now a new file popped up on the side freeze classes dodgy dart and there we have user from JSON and user to JSON which is a nice thing to see so what we can now do with really just a few lines of code is that we now have a data class with Val equality peewit method all of that nice stuff together with json serialization so what we can now do is that we can still have a user right here matt h is 20 and now we can convert it to json so final serialize is equal to user dot to json and as you can see this will output map string dynamic and then we can also deserialize it so we can convert a serialized map using the factory user that from json which was generated by priest so we can just pass in the serialized map and now we can actually print serialized and also d serialize so let's take a look at all of this we now have plain regular data class we then serialize it and then we also BCI's it so let's see the output and indeed we can see that we have printed out a map the serialized JSON basically and then also the deserialized user object everything works and again if you want to go through this lesson at your own pace make sure to check out the written tutorial from the link in the video description now let's go on to unions or otherwise known as sealed classes so basically if you are not yet convinced to introduce this freest package just for having these amazingly simple and awesome data classes I think that you are going to be convinced once you see the elegance with which unions can be created let's again take a look at the beautiful Cartland version of sealed classes and then let's try to replicate this with dart with this awesome freezed package so I will just create a new file here change the language to caught link just so we can see everything and now I'm just going to copy Semmy valid Catalan code right over here so even if you are not familiar with Catalan at all you are gonna be able to understand what's going on here so basically see of classes are just regular classes with some amazing features like for example exhaustive switch we're going to get to implement an exhaustive switch in dart later on in this tutorial but basically exhaustive switch just doesn't let you to forget about the particular case for example you cannot forget about the subtract here it would give you an error right this is called exhaustive switch or in Catalan is actually called a when expression so in Catalan you can create CF classes which are either nested like this or you can have SIL classes which are not nested and what's the difference well with nested classes in Catalan you can only create instance of add by specifying operation that add and pass in some sort of a value one two three right this is with the nested sealed class however if you are using non nested sealed class you can instantiate individual cases directly so you do not need to prefix it with operation but you just specify add and then when you use this instance inside a one expression it still works you can ask forget about subtract if you do you are still going to get an error so how can we replicate something like this this beautiful functionality of Catalan in Dart well of course we can replicate it with freeze and we can even replicate this sort of nesting of classes of course dart does not support nested classes at all but with the help of the free Spanish we can sort of get around this issue so let's get right to it inside the same file which holds our data class we are also going to create Union I'm just going to copy this user class pasted below and I'm going to change its name to be operation nested because we want to replicate the code which you could see in Kaplan now replace all of the references of user with operation nested we actually aren't going to be converting it to JSON or from JSON although you can absolutely use JSON serialization even with Union types where it is not going to do it in this quick tutorial and once we have replaced all of the references of user with operation nested we're going to make this operation accept an integer value and also we're going to actually make it named and of course this should not be operation nested but add so what are we actually doing here if you remember about the cotton code which I should probably not have deleted but whatever basically here we are creating a nested class so to say because this operation nested can be instantiated only by using this factory constructor and the actual class add is packaged private as you can see by this underscore before it call let's just generate the code needed for this and let me just quickly show you what I mean by package private and that we can only use this add factory constructor from main de dart so if I say operation nested dot add one this is valid code but if I say add there is no class called ad right kind of obvious so this is in other words the thing which you would call a nested sealed class in Catalan you can only instantiate this instance of AD by using the factory constructor and not the actual constructor of the class itself but if we change this add class to not have an underscore so it's going to be public now we are going to be able to both use the factory constructor and also the actual just class constructor without any issues make sense I hope so so let's now delete all of this code and let's get back to the business of unions let's make this again back into a nested or sort of nested Union by providing the underscore and of course this would not be a union if it did not have multiple case classes if you are coming from Scala at least so this will be subtract subtracting a value still subtract save that so that it can get generated and now what can we actually do with this kind of a Union well let's hop into main de Dart and we are going to use it inside a function I will just quickly copy and paste the function from the written tutorial to which you can get from the link in the video description this function is pretending to do something useful here so we are performing operation we take an integer operand and an operation which is going to be our Union here so the operation can be either add or subtract and then we use the when expression or in this case a when method and the operation union where we can now just ignore something we're going to get this squiggly line saying that the parameter subtract is required and you can also promote this info message to be a fully blown error message and to learn how to do that how to use linking in dart to keep your codebase healthy check out the tutorial from the cart in the corner but here it suffices that we just get info message we don't really care in this example simple app basically when we are adding something we're going to perform addition of course and when we are subtracting we are going to say operand - value and then return the result of this operation from this perform operation function so now let's use this function we are going to put its result into final result it's gonna be equal to perform operation the up-train will be for example 2 and then we are going to perform addition so operation missed it dot e-d-u want to add 2 + 2 + 2 is of course for so printing this result should print out for let's see if I am correct if my math skills are not failing me I hope that and of course it's 4 so I did not forget math I'm really glad for that so we have just created operation nested but of course we can also create the operation non nested and I will show you what that will mean for us maybe if I just rename this to operation which will imply not nested awesome so now we have this operation and we are going to remove the underscores from add and subtract so now these things are gonna be able to be instantiated individually what we can now do is hop into main the dart change all references to operation Nesta to be just operation and now we can still just instantiate operation dot add to that's still perfectly doable and there is no issue with that and it's still going to print out for but we can also instantiate just add two now it's possible and running this it's still going to result in a perfectly valid and manageable by enable and readable code so when would you need to have public case classes and when would you rather have them be private I think that when you are using the block library from Felix angle off then you may find it useful to have your case classes or your events and states in the case of block be public so that you do not need to instantiate them by using the prefix of the Union but you can just instantiate them by calling add or subtract or some sort of a name of the event or name of the state respectively if you are using something like block it's really up to you there is no clear winner here but just know that you can also have nested sort of sealed classes and non nested public case classes here and really sorry I am jumping between the terminology of unions seal classes from Kathleen and case classes from Scala all over the place now but I hope you get the point this is all cool and nice we have just run through most of the stuff which is available in the freest package but there's still a bunch of more things to talk about that's because up until now we have covered only the when method which is mimicking the when expression from Kotlin which is an exhaustive switch basically but in addition to when there is also maybe when in the case of maybe when you can safely ignore a certain K of the union and instead you must you absolutely must provide or else which is going to return some catch-all fallback thing like for example minus 1 because returning minus 1 as error code is always the best practice you can do right so this is maybe when pretty simple and then in addition to when you can also use map so map compared to when does not provide you with the actual integer value as you can see we now cannot perform a plus operation on the integer operands it says that it cannot be assigned to the parameter type num that's because the value is actually the add class instance or the subtract instance respectively so basically while when these structures the contents of the case classes to be integers in this case they are these structured to be integers map does not destructor the contents it just passes you the whole case class and and lets it be sorted out by you manually so let's rename these values to be case classes to be more meaningful and then we can get the value from them like this we can access also the copy wave method we can also map through the case class itself we can convert it to string we just have the fully-blown case class which is actually also a data class because if you take a look at this this add and subtract case classes are really the same thing as is the user class in the case of the single case Union you could call it because data class is with freeze our religious unions which have just a single case and they do not have named factory they have a factory without an enema so basically there is no difference between data classes and unions with fries but yeah you get the point here so let's get the value we do not need to do anything else with this case class we do not need to call copy with for example and having done all of this we can still run this program without any issues we're gonna see the output is four so still we have a valid program and you may ask when should I use when with these structures things for me and when should I use map well for example you can use map if you are using the block library and you would like to output different widgets from this map function so in that case you would probably want your state's your state classes to arrive as actual classes and not just as these structures variables but again it's up to you you are the one who decides what happens now onto a bonus before we leave this video in the written tutorial you have all of the vs code snippets available so let me show you right now what kind of BS code snippets I have prepared because as you can see creating data classes and unions can be quite time-consuming so because of that I have prepared snippets for PTF which automatically creates a part statement with the proper file name for the freeze package there is also pts which creates the regular dot G the dart part statement then we have F data class so for example user two and then we can specify it in H right here cool then we have F Union with one single case so let's just call it some union it's going to have one case hello hello it's going to be private cool this should work oh it doesn't I need to fix the actual snippet call so I have just found an issue when you get this snippet it's actually going to be fixed the hello name of the factory will be created at the proper place so we don't worry about that and then we can also create another F Union case it will be called against some Union hello again at the incorrect place pardon me actually this one should be named goodbye private goodbye and you can immediately see just how much keystrokes we saved of course when this is actually going to be generated properly at the proper place this name of the factory you're going to save even more keystrokes than I did right now so you can get all of these nice code snippets from the link in the video description from the written tutorial so just get them use them and just put them into your user snippets by hitting f1 in vs code or ctrl shift or command shift P in vs code configure user snippets dart JSON so just click here and now you can just paste them all into this dart add JSON file and you are going to be good to go so to go through this tutorial at your own pace once again to get all of the snippets and all of that get all of the code check out the written tutorial available from the link in the description and be sure to show some support to hear me by giving this package a like on pop in a star on github it already has a bunch of stars and likes because you know it's Remy it was a lazy theory this is something you just gotta like it right if you are a proper floral developer but still show him some support like install this package we now finally have a data and seal class solution which does not compromise on anything and that is a nice thing to see and if you are serious about becoming a great flower developer who can build the real apps for clients or at a job go to flutter that education link is also in the video description to get the top curated flower news and resources aimed at improving your app development career over there you can also subscribe to my mailing list to get the best photo resources delivered weekly right into your inbox and if you don't want to miss more tutorials like this also more in-depth tutorials about programming paradigms and how to build really complex apps production great be sure to subscribe to this channel and also join notification squad by hitting the Bell button to make sure you grow your flower skills because here on reason coder 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 helps you with understanding data classes shield classes and also the free SPAC egde give this video while I can also share it with our developers who are surely going to find it beneficial too if you have anything to say leave a comment down below and see you in the next video [Music]
Info
Channel: Reso Coder
Views: 36,543
Rating: undefined out of 5
Keywords: resocoder, tutorial, programming, code, programming tutorial, flutter, flutter tutorial, dart sealed, dart sealed unions, dart sealed class, dart enum, dart enum extension, dart data class, dart tutorial, dart freezed, flutter freezed, dart sum types
Id: ApvMmTrBaFI
Channel Id: undefined
Length: 36min 28sec (2188 seconds)
Published: Tue Feb 11 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.