{"id":61241,"date":"2024-04-12T11:25:33","date_gmt":"2024-04-12T05:55:33","guid":{"rendered":"https:\/\/www.tothenew.com\/blog\/?p=61241"},"modified":"2024-04-16T11:40:19","modified_gmt":"2024-04-16T06:10:19","slug":"demystifying-freezed-annotations-mastering-data-modeling-for-complex-state-in-flutter-%f0%9f%a5%b6","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/demystifying-freezed-annotations-mastering-data-modeling-for-complex-state-in-flutter-%f0%9f%a5%b6\/","title":{"rendered":"Demystifying Freezed Annotations: Mastering Data Modeling for Complex State in Flutter \ud83e\udd76"},"content":{"rendered":"<h3 class=\"graf graf--h3 graf--empty\"><\/h3>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" loading=\"lazy\" class=\"graf-image alignnone\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1600\/1*lgt9PB1PYTyOTtI497--3Q.png\" alt=\"Demystifying Freezed Annotations: Mastering Data Modeling for Complex State in Flutter \" width=\"1600\" height=\"914\" data-image-id=\"1*lgt9PB1PYTyOTtI497--3Q.png\" data-width=\"4032\" data-height=\"2304\" data-is-featured=\"true\" \/><\/figure>\n<p>The world of Flutter development thrives on well-structured and maintainable code. When it comes to data modeling for intricate state management, the <code class=\"markup--code markup--blockquote-code\">freezed<\/code> package emerges as a champion. It offers a powerful annotation toolkit that empowers you to create robust and expressive data classes. This blog post delves into four key annotations \u2013 <code class=\"markup--code markup--blockquote-code\">@Union<\/code>, <code class=\"markup--code markup--blockquote-code\">@with<\/code>, <code class=\"markup--code markup--blockquote-code\">@case<\/code>, and <code class=\"markup--code markup--blockquote-code\">@equatable<\/code> \u2013 and explores how they work together to elevate your state management game in Flutter.<\/p>\n<h2 class=\"graf graf--p\"><strong class=\"markup--strong markup--p-strong\">The Power of Immutability: Why Freezed?<\/strong><\/h2>\n<p class=\"graf graf--p\">Traditional Dart classes are mutable, meaning their internal data can be altered after creation. This mutability can introduce inconsistencies and unforeseen behavior in your application, leading to debugging challenges. Freezed tackles this by promoting immutability. When you use <code class=\"markup--code markup--p-code\">freezed<\/code> it to define a data class, it automatically generates an immutable counterpart with a fixed set of properties. This ensures data integrity and simplifies reasoning about your application&#8217;s state throughout its lifecycle.<\/p>\n<h2 class=\"graf graf--h4\"><strong class=\"markup--strong markup--h4-strong\">Introducing the Key Players: Freezed Annotations<\/strong><\/h2>\n<p class=\"graf graf--p\">Freezed provides a comprehensive set of annotations that work in concert to streamline your data modeling process, particularly for complex state scenarios. Let\u2019s explore four crucial ones:<\/p>\n<ul class=\"postList\">\n<li class=\"graf graf--li\"><strong class=\"markup--strong markup--li-strong\">@Union:<\/strong> Define Sealed Union Types<br \/>\nThis annotation allows you to create a set of possible states for your data class, representing different scenarios within your application. Imagine a <code class=\"markup--code markup--li-code\">UserState<\/code> union type with states like <code class=\"markup--code markup--li-code\">UserInitial<\/code>, <code class=\"markup--code markup--li-code\">UserLoading<\/code>, <code class=\"markup--code markup--li-code\">UserLoaded<\/code>, and <code class=\"markup--code markup--li-code\">UserError<\/code>. Each state holds relevant information specific to its purpose.<\/li>\n<\/ul>\n<blockquote>\n<pre class=\"graf graf--pre graf--preV2\" data-code-block-mode=\"1\" data-code-block-lang=\"dart\"><span class=\"pre--content\" style=\"color: #999999;\"><span class=\"hljs-comment\">\/\/ This code demonstrates the use of @Union to define sealed union types<\/span>\r\n\r\n<span class=\"hljs-meta\">@freezed<\/span>\r\n<span class=\"hljs-keyword\">abstract<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">UserState<\/span> <span class=\"hljs-title\">with<\/span> <span class=\"hljs-title\">_<\/span>$<span class=\"hljs-title\">UserState<\/span> <\/span>{\r\n  <span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-keyword\">factory<\/span> UserState.initial() <span class=\"hljs-comment\">\/\/ Represents the initial state of the user<\/span>\r\n      = UserInitial;\r\n  <span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-keyword\">factory<\/span> UserState.loading() <span class=\"hljs-comment\">\/\/ Represents a loading state while fetching user data<\/span>\r\n      = UserLoading;\r\n  <span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-keyword\">factory<\/span> UserState.loaded(User user) <span class=\"hljs-comment\">\/\/ Represents a state where user data is loaded successfully<\/span>\r\n      = UserLoaded;\r\n  <span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-keyword\">factory<\/span> UserState.error(<span class=\"hljs-built_in\">String<\/span> message) <span class=\"hljs-comment\">\/\/ Represents an error state with an error message<\/span>\r\n      = UserError;\r\n}<\/span><\/pre>\n<\/blockquote>\n<ul class=\"postList\">\n<li class=\"graf graf--li\"><strong class=\"markup--strong markup--li-strong\">@with:<\/strong> Combine Existing Classes for Enhanced Data<br \/>\nThis annotation allows you to combine properties from multiple existing data classes into a new class. This is particularly useful when you need to extend functionality or create a data class with properties from various sources.<\/li>\n<\/ul>\n<blockquote>\n<pre class=\"graf graf--pre graf--preV2\" data-code-block-mode=\"1\" data-code-block-lang=\"dart\"><span class=\"pre--content\" style=\"color: #999999;\"><span class=\"hljs-comment\">\/\/ This code demonstrates the use of @with to combine properties from existing classes<\/span>\r\n\r\n<span class=\"hljs-meta\">@freezed<\/span>\r\n<span class=\"hljs-keyword\">abstract<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">ProductDetails<\/span> <span class=\"hljs-title\">with<\/span> <span class=\"hljs-title\">_<\/span>$<span class=\"hljs-title\">ProductDetails<\/span> <\/span>{\r\n  <span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-keyword\">factory<\/span> ProductDetails.fromProduct(Product product)\r\n      <span class=\"hljs-meta\">@With<\/span>&lt;Product&gt;() <span class=\"hljs-comment\">\/\/ Combine properties from the Product class<\/span>\r\n      =&gt; ProductDetails(\r\n            id: product.id,\r\n            name: product.name,\r\n            description: product.description,\r\n            <span class=\"hljs-comment\">\/\/ Add additional properties specific to product details<\/span>\r\n          );\r\n\r\n  <span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-keyword\">factory<\/span> ProductDetails({\r\n    <span class=\"hljs-keyword\">required<\/span> <span class=\"hljs-built_in\">String<\/span> id,\r\n    <span class=\"hljs-keyword\">required<\/span> <span class=\"hljs-built_in\">String<\/span> name,\r\n    <span class=\"hljs-keyword\">required<\/span> <span class=\"hljs-built_in\">String<\/span> description,\r\n    <span class=\"hljs-comment\">\/\/ Additional details specific to product details<\/span>\r\n  }) = _ProductDetails;\r\n}<\/span><\/pre>\n<\/blockquote>\n<ul class=\"postList\">\n<li class=\"graf graf--li\"><strong class=\"markup--strong markup--li-strong\">@case:<\/strong> Customize Generated Constructor Names<br \/>\nBy default, <code class=\"markup--code markup--li-code\">freezed<\/code> generates constructor names based on the class name and state names. However, <code class=\"markup--code markup--li-code\">@case<\/code> allows you to customize these names for improved readability and clarity in your code.<\/li>\n<\/ul>\n<blockquote>\n<pre class=\"graf graf--pre graf--preV2\" data-code-block-mode=\"2\" data-code-block-lang=\"dart\"><span class=\"pre--content\" style=\"color: #999999;\"><span class=\"hljs-comment\">\/\/ This code demonstrates the use of @case to customize constructor names<\/span>\r\n\r\n<span class=\"hljs-meta\">@freezed<\/span>\r\n<span class=\"hljs-keyword\">abstract<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">CartEvent<\/span> <span class=\"hljs-title\">with<\/span> <span class=\"hljs-title\">_<\/span>$<span class=\"hljs-title\">CartEvent<\/span> <\/span>{\r\n  <span class=\"hljs-meta\">@case<\/span>(<span class=\"hljs-string\">'add_to_cart'<\/span>) <span class=\"hljs-comment\">\/\/ Customize constructor name for better readability<\/span>\r\n  <span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-keyword\">factory<\/span> CartEvent.addItem(Product product) = AddItem;\r\n\r\n  <span class=\"hljs-meta\">@case<\/span>(<span class=\"hljs-string\">'remove_from_cart'<\/span>) <span class=\"hljs-comment\">\/\/ Customize constructor name for better readability<\/span>\r\n  <span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-keyword\">factory<\/span> CartEvent.removeItem(Product product) = RemoveItem;\r\n}<\/span><\/pre>\n<\/blockquote>\n<ul class=\"postList\">\n<li class=\"graf graf--li\"><strong class=\"markup--strong markup--li-strong\">@Equatable (from the <\/strong><code class=\"markup--code markup--li-code\">equatable<\/code><strong class=\"markup--strong markup--li-strong\"> package):<\/strong> Ensure Proper Object Comparison<br \/>\nImmutability is valuable, but effectively comparing data objects for equality is also crucial for state management logic. <code class=\"markup--code markup--li-code\">@Equatable<\/code> (used alongside <code class=\"markup--code markup--li-code\">freezed<\/code>) assists in generating methods like <code class=\"markup--code markup--li-code\">==<\/code> and <code class=\"markup--code markup--li-code\">hashCode<\/code> based on the data class properties, ensuring proper object comparison during state updates.<\/li>\n<\/ul>\n<blockquote>\n<pre class=\"graf graf--pre graf--preV2\" data-code-block-mode=\"2\" data-code-block-lang=\"dart\"><span class=\"pre--content\" style=\"color: #999999;\"><span class=\"hljs-comment\">\/\/ This code demonstrates the use of @Equatable for proper object comparison<\/span>\r\n\r\n<span class=\"hljs-meta\">@freezed<\/span>\r\n<span class=\"hljs-meta\">@Equatable<\/span>\r\n<span class=\"hljs-keyword\">abstract<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Filter<\/span> <span class=\"hljs-title\">with<\/span> <span class=\"hljs-title\">_<\/span>$<span class=\"hljs-title\">Filter<\/span> <\/span>{\r\n  <span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-keyword\">factory<\/span> Filter({\r\n    <span class=\"hljs-meta\">@Default<\/span>(VisibilityFilter.all) VisibilityFilter visibilityFilter,\r\n  }) = _Filter;\r\n\r\n  <span class=\"hljs-meta\">@override<\/span>\r\n  <span class=\"hljs-built_in\">List<\/span>&lt;<span class=\"hljs-built_in\">Object?<\/span>&gt; <span class=\"hljs-keyword\">get<\/span> props =&gt; [visibilityFilter]; <span class=\"hljs-comment\">\/\/ Define properties used for equality comparison<\/span>\r\n}\r\n\r\n<span class=\"hljs-keyword\">enum<\/span> VisibilityFilter { all, active, completed }<\/span><\/pre>\n<\/blockquote>\n<h3 class=\"graf graf--h4\"><strong class=\"markup--strong markup--h4-strong\">Benefits of Using These Annotations with\u00a0Freezed<\/strong><\/h3>\n<figure class=\"graf graf--figure\"><img decoding=\"async\" class=\"graf-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1600\/0*a7bUA4DTO9s1jXtI.gif\" data-image-id=\"0*a7bUA4DTO9s1jXtI.gif\" data-width=\"240\" data-height=\"296\" \/><\/figure>\n<ul class=\"postList\">\n<li class=\"graf graf--li\"><strong class=\"markup--strong markup--li-strong\">Expressive Data Modeling:<\/strong> Define clear and concise states for your application, making your state management logic more readable and maintainable.<\/li>\n<li class=\"graf graf--li\"><strong class=\"markup--strong markup--li-strong\">Reduced Boilerplate:<\/strong> These annotations eliminate the need for manually writing constructors, copy methods, and equality checks in many cases.<\/li>\n<li class=\"graf graf--li\"><strong class=\"markup--strong markup--li-strong\">Improved Readability:<\/strong> Customize constructor names and leverage clear state definitions to enhance code clarity for both you and your team.<\/li>\n<li class=\"graf graf--li\"><strong class=\"markup--strong markup--li-strong\">Enhanced Type Safety:<\/strong> By defining data structures with annotations, you benefit from Dart\u2019s static type checking, helping to prevent runtime errors.<\/li>\n<li class=\"graf graf--li\"><strong class=\"markup--strong markup--li-strong\">Stronger Testability:<\/strong> Immutable data classes and proper object comparison using <code class=\"markup--code markup--li-code\">@Equatable<\/code> lead to significantly more reliable and testable code.<\/li>\n<\/ul>\n<h3 class=\"graf graf--h4\"><strong class=\"markup--strong markup--h4-strong\">Conclusion: Building a Solid Foundation for State Management<\/strong><\/h3>\n<p class=\"graf graf--p\">By leveraging annotations like <code class=\"markup--code markup--p-code\">@Union<\/code>, <code class=\"markup--code markup--p-code\">@with<\/code>, <code class=\"markup--code markup--p-code\">@case<\/code>, and <code class=\"markup--code markup--p-code\">@equatable<\/code> in conjunction with <code class=\"markup--code markup--p-code\">freezed<\/code>, you can construct well-structured and expressive data classes that form the foundation for robust and maintainable state management in your Flutter applications. With cleaner code, improved readability, enhanced type safety, and stronger testability, <code class=\"markup--code markup--p-code\">freezed<\/code> you can focus on crafting exceptional user experiences while keeping your state logic clear and predictable. So, embrace the power of annotations and take your <a href=\"https:\/\/www.tothenew.com\/digital-product-engineering\/mobility\/flutter\">Flutter development<\/a> to the next level!<\/p>\n<div class=\"ap-custom-wrapper\"><\/div><!--ap-custom-wrapper-->","protected":false},"excerpt":{"rendered":"<p>The world of Flutter development thrives on well-structured and maintainable code. When it comes to data modeling for intricate state management, the freezed package emerges as a champion. It offers a powerful annotation toolkit that empowers you to create robust and expressive data classes. This blog post delves into four key annotations \u2013 @Union, @with, [&hellip;]<\/p>\n","protected":false},"author":1763,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":25},"categories":[3429,4687,1772,1994],"tags":[4968,5828],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/61241"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/1763"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=61241"}],"version-history":[{"count":2,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/61241\/revisions"}],"predecessor-version":[{"id":61311,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/61241\/revisions\/61311"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=61241"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=61241"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=61241"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}