<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Nikki Goel</title>
    <description>The latest articles on DEV Community by Nikki Goel (@nicks101).</description>
    <link>https://dev.to/nicks101</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F536876%2Feb8b24f9-b91f-4d2a-8808-6bda6703556b.jpg</url>
      <title>DEV Community: Nikki Goel</title>
      <link>https://dev.to/nicks101</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nicks101"/>
    <language>en</language>
    <item>
      <title>Tests are for Future Releases</title>
      <dc:creator>Nikki Goel</dc:creator>
      <pubDate>Sun, 24 Aug 2025 08:00:12 +0000</pubDate>
      <link>https://dev.to/nicks101/tests-are-for-future-releases-2lcj</link>
      <guid>https://dev.to/nicks101/tests-are-for-future-releases-2lcj</guid>
      <description>&lt;p&gt;I used to think of tests as just a final check to confirm whether a feature worked. That perspective shifted a few years ago when I had shipped a feature, and later a teammate made changes that unintentionally broke a small but important part of it. No one noticed during code reviews or QA, but a simple code comment I had left — reminding myself to manually test an edge case — caught the issue.&lt;/p&gt;

&lt;p&gt;It made me realise that tests aren’t just about verifying today’s work; they’re about safeguarding tomorrow’s. Whether it’s me revisiting the code months later or someone else making changes, tests act as a safety net, ensuring the feature continues to work as intended.&lt;/p&gt;

&lt;p&gt;So when I joined my current organisation, one of the first things I proposed to the mobile team, was introducing tests. We have four mobile applications: two internal and two consumer-facing apps. One consumer-facing app that I work on is hybrid (Flutter + native Android and iOS) and has a team of 7-10 people.&lt;br&gt;
Being a startup, we’re always chasing the next release, sprint, or metric. This often means shifting people between features. Breaking your own code is one thing; breaking someone else’s is almost guaranteed in this environment.&lt;/p&gt;

&lt;p&gt;Given our user base and the need for stability, tests made sense. Everyone agreed, so I started a POC.&lt;br&gt;
I picked a small Flutter module with two screens and built an internal framework using flutter_test. For the POC, I wrote two unit tests and one integration test that covered 4–5 edge-case flows. This meant setting up mocks for APIs, local storage, and analytics, setting up flavors, dependency injection tweaks, and documentation.&lt;/p&gt;

&lt;p&gt;Then I showed this to the mobile engineering team.&lt;/p&gt;

&lt;p&gt;To set the company’s mindset (since tests are considered heavy resource investment), I wrote separate documentation on test coverage. I suggested starting with tests for highly bug-prone code. Later if time permitted, we could add tests for business-critical features. The goal wasn’t 100% coverage, it was achieving the stability and saving time on bug fixes in future iterations.&lt;/p&gt;

&lt;p&gt;The team’s initial response was hesitant, but it highlighted the challenge of balancing resources and stability in a startup.&lt;/p&gt;

&lt;p&gt;It was a little discouraging, but I continue to suggest tests whenever a production bug occurs.&lt;br&gt;
I think in this fast-moving startup, tests should not be treated as a luxury, an afterthought. Even a handful of tests for critical use cases can save us when teammates switch, features evolve, or releases get rushed.&lt;/p&gt;

</description>
      <category>devjournal</category>
      <category>testing</category>
      <category>workplace</category>
      <category>architecture</category>
    </item>
    <item>
      <title>When AI Suddenly Took Center Stage</title>
      <dc:creator>Nikki Goel</dc:creator>
      <pubDate>Tue, 12 Aug 2025 17:58:00 +0000</pubDate>
      <link>https://dev.to/nicks101/when-ai-suddenly-took-center-stage-1043</link>
      <guid>https://dev.to/nicks101/when-ai-suddenly-took-center-stage-1043</guid>
      <description>&lt;p&gt;A sudden AI interest in my company has left me avoiding it as much as possible.&lt;/p&gt;

&lt;p&gt;I’ve been using Copilot for 3 years now and have been very happy with it. When ChatGPT launched, I quickly created an account and it integrated smoothly into my workflow. I promoted both Copilot and ChatGPT for the engineering team at my workplace—at least the mobile team—but to no avail.&lt;/p&gt;

&lt;p&gt;That’s when the AI push really began. Over the past 4 months, as AI trends have surged, all the employees were encouraged to try them.&lt;br&gt;
It started with a trial subscription of Cursor, with a lot of noise about MCPs. The focus was on using Cursor for our development, trying out various prompts, reviewing the code, and if it looked good, moving it to production.&lt;br&gt;
I won’t go into the company’s reason for pushing AI tools.&lt;/p&gt;

&lt;p&gt;For context, I’m a mobile developer using Android Studio, emulator(s), Chrome/Arc, etc. Adding another IDE to this stack wasn’t something I was eager for, especially since Copilot was already doing the job.&lt;br&gt;
Given the encouragement, we tried it for one sprint. The results were not good, at least for the mobile team. The pressure to get the Cursor to make the UI from Figma designs with code quality that was just about acceptable… that was a tough week.&lt;/p&gt;

&lt;p&gt;First, we decided to test it on something fresh. We got the Figma Mac App, integrated it’s MCP server—it was way better than Figma web for some reason. After many trials, prompts expanded from 2–3 lines to a full page (about 100 lines), basically a small PRD + TRD (Product and Technical Requirements Document). This included the feature explanation, all the Classes or file names to be updated, API contract sample, localisation rules, event rules, code structure rules, and more.&lt;br&gt;
The output we got was somewhat intern-level work. It worked fine but needed a thorough review and significant refactoring. It did well at making model classes, repository functions and, small UI components (for Flutter). It fell short on UI code structure and state management.&lt;/p&gt;

&lt;p&gt;All this was done in 1.5 days. Actual estimates were 3 days. So, a big win for the company, as it claimed to increase productivity by 50%. However, reviewing, fixing bugs and, refactoring took longer—so the total time was the same.&lt;/p&gt;

&lt;p&gt;Encouraged by this partial win, we tried Cursor for an enhancement task in a released feature. This did not work at all. Writing detailed prompts took time; testing the result and rewriting the prompts took even more time and left the engineer frustrated, taking extra coffee breaks.&lt;/p&gt;

&lt;p&gt;Since then, everyone has a different tool and workflow. Some are using Claude on the web, copy—pasting the code snippets on IDE. Others have embraced switching the IDEs between Cursor, Android Studio and web browser. I have been using the Copilot’s IDE extension, ChatGPT + web browser for regular web searches.&lt;br&gt;
Lately we’ve also been trying out Copilot PR review. It seems odd: AI reviewing the code written by AI. It did give some good suggestions though. Let’s see how this works out.&lt;/p&gt;

&lt;p&gt;I like the code completion in small chunks of code—easy to review, refactor, and test. Copilot works for me as I don’t have to switch to another code editor. For all other mundane tasks, ChatGPT works fine. In fact, switching from IDE to web browser for ChatGPT works well—it helps me focus on exactly what I’m looking for. For web searches, I still check Stack Overflow from time to time and read articles/blogs for learning, research, and debugging—focusing on human-written content.&lt;/p&gt;

&lt;p&gt;I do want to try a local LLM, LM Studio as well.&lt;br&gt;
I’m curious to see how these tools evolve, but for now, I’ll stick with what fits my workflow and leave the hype to others.&lt;/p&gt;

</description>
      <category>devjournal</category>
      <category>softwareengineering</category>
      <category>ai</category>
      <category>workplace</category>
    </item>
    <item>
      <title>Navigating the Waters of Technical Curiosity: A Confession</title>
      <dc:creator>Nikki Goel</dc:creator>
      <pubDate>Tue, 08 Aug 2023 17:55:11 +0000</pubDate>
      <link>https://dev.to/nicks101/navigating-the-waters-of-technical-curiosity-a-confession-9hl</link>
      <guid>https://dev.to/nicks101/navigating-the-waters-of-technical-curiosity-a-confession-9hl</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Hey there! I'm trying out something new today. This is not a tutorial blog but more of a personal development blog.&lt;br&gt;&lt;br&gt;
It has no conclusion or takeaway if that's what you're looking for. This blog serves as a confession for me trying to rationalize my new area of interest.&lt;/p&gt;

&lt;h2&gt;
  
  
  Embracing a New Horizon
&lt;/h2&gt;

&lt;p&gt;In the past few months, I have become interested in various subjects other than mobile app development, my primary field of expertise.&lt;br&gt;&lt;br&gt;
These subjects span not just across tech stacks like backend and frontend but delve into the concepts such as understanding compilers, virtual machines, computer networking, databases internal working, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Deep Dive into the Unknown
&lt;/h2&gt;

&lt;p&gt;It has been and continues to be a thrilling adventure for me. I've been reading about how compilers work, how programming languages are created, exploring the nuanced variations between them, how technologies like Firebase Cloud Firestore work, the physical path of the TCP/IP model, etc.&lt;/p&gt;

&lt;p&gt;This has been a fascinating switch from learning how to use tech, be it a programming language, a framework, or a third-party service, to how is that technology created, its purpose, and the voids they endeavor to fill.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Distracted Pursuit
&lt;/h2&gt;

&lt;p&gt;I have not been able to concentrate on app development as a whole. Rather than swiftly implementing features or eradicating bugs, I often find myself entangled in the hows and whys of technology.&lt;br&gt;&lt;br&gt;
For example, while implementing a push notification feature in a mobile app, I side-tracked and started researching how does push notifications work, how was this invented in the first place, which protocols it uses, and more.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Allure of Exploration
&lt;/h2&gt;

&lt;p&gt;As I continue to explore this captivating realm, my learning resources have undergone a transformation.&lt;br&gt;&lt;br&gt;
From youtube videos and courses, I'm now moving to podcasts, white papers, research papers, books, GitHub feature proposals, and beyond.&lt;/p&gt;

&lt;p&gt;This shift has also influenced my blog ideas, which are now more inclined towards delving into the "what" and "how" aspects rather than solely focusing on straightforward tutorials.&lt;/p&gt;

&lt;p&gt;This transition is ironic, considering my very &lt;a href="https://blog.nikkigoel.com/what-is-setstate-in-flutter-and-when-to-use-it-1" rel="noopener noreferrer"&gt;first blog&lt;/a&gt; embarked on a similar path.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I want to point out that this does not discredit the importance of the instructional content. I've certainly authored such blogs and and I continue to benefit from the insights of others. These resources remain integral to my daily routine.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  A Dilemma Unveiled
&lt;/h2&gt;

&lt;p&gt;This transition challenges me to realign my focus at work, finding an equilibrium between work and research.&lt;/p&gt;

&lt;p&gt;The more I dwell on this, the more I become disinterested in my current work.&lt;br&gt;&lt;br&gt;
I may have gone down a few rabbit holes when I should've been focusing on finishing that feature.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Joy of Curiosity
&lt;/h2&gt;

&lt;p&gt;It's hard to say whether this is just a passing phase or a lasting change.&lt;br&gt;&lt;br&gt;
Perhaps trying out a challenging project could help me realign my focus.&lt;/p&gt;

&lt;p&gt;One thing's for sure: I'm finding a lot of joy in exploring the uncharted waters of my newfound curiosity.&lt;/p&gt;

</description>
      <category>devjournal</category>
      <category>softwareengineering</category>
      <category>todayisearched</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Custom Serializer with built_value in Dart and Flutter</title>
      <dc:creator>Nikki Goel</dc:creator>
      <pubDate>Tue, 21 Feb 2023 10:31:13 +0000</pubDate>
      <link>https://dev.to/nicks101/custom-serializer-with-builtvalue-in-dart-and-flutter-4df3</link>
      <guid>https://dev.to/nicks101/custom-serializer-with-builtvalue-in-dart-and-flutter-4df3</guid>
      <description>&lt;p&gt;The package, &lt;a href="https://pub.dev/packages/built_value" rel="noopener noreferrer"&gt;&lt;code&gt;built_value&lt;/code&gt;&lt;/a&gt; is used for creating immutable classes in Dart with JSON serialization. It's a great package and uses &lt;code&gt;build_runner&lt;/code&gt; to create generated files to avoid boilerplate code.&lt;br&gt;&lt;br&gt;
But if you've ever tried to deserialize a model class with a collection generic type like &lt;code&gt;BuiltList&lt;/code&gt;, it'll drive you mad!&lt;/p&gt;

&lt;p&gt;So, here is our goal. We're going to customize &lt;code&gt;build_value&lt;/code&gt;'s serializer such that it can deserialize properties like &lt;code&gt;BuiltList&amp;lt;T&amp;gt; get data&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Application&lt;/li&gt;
&lt;li&gt;Setting up Models&lt;/li&gt;
&lt;li&gt;What's the problem?&lt;/li&gt;
&lt;li&gt;
Finally, a solution!

&lt;ul&gt;
&lt;li&gt;1. Adding &lt;code&gt;specifiedType&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;2. Adding &lt;code&gt;addBuilderFactory&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;This solution works. Why?&lt;/li&gt;
&lt;li&gt;Simplifying the solution&lt;/li&gt;
&lt;li&gt;Going one step further&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;li&gt;Final Note&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Here's the &lt;a href="https://github.com/nicks101/flutter_tutorials/tree/main/built_value_generic" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt; with all the code.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Application &lt;a id="application"&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The inspiration for this is a straightforward use case:&lt;br&gt;&lt;br&gt;
Creating a generic pagination model with the &lt;code&gt;BuiltList&amp;lt;T&amp;gt; get data&lt;/code&gt; property.&lt;br&gt;&lt;br&gt;
So all paginated APIs can use this one model with a different data type for the data field. Rest of the fields like &lt;code&gt;current_page&lt;/code&gt;, &lt;code&gt;next_page&lt;/code&gt;, etc. are common for all paginated APIs.&lt;/p&gt;
&lt;h2&gt;
  
  
  Setting up Models &lt;a id="setup"&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Create a file called &lt;code&gt;generic_model.dart&lt;/code&gt;. Using the snippets &lt;code&gt;bvtgsf&lt;/code&gt; from the &lt;code&gt;built_value_snippets&lt;/code&gt; package in VS Code (or any other IDE), we get the following class.&lt;br&gt;&lt;br&gt;
I've made some changes to it as required.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;/// Add the import for the serializer&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'serializers.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;part&lt;/span&gt; &lt;span class="s"&gt;'generic_model.g.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GenericModel&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="n"&gt;Built&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;,&lt;/span&gt; &lt;span class="n"&gt;GenericModelBuilder&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;_&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;factory&lt;/span&gt; &lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="kt"&gt;Function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GenericModelBuilder&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt; &lt;span class="n"&gt;updates&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="n"&gt;_$GenericModel&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;

  &lt;span class="kt"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;dynamic&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;toJson&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;/// Add the typecast [Map&amp;lt;String, dynamic&amp;gt;] to fix the error&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;serializers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;serializeWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;serializer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kt"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;dynamic&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;/// Add [&amp;lt;T&amp;gt;] to deserialize generic type values&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fromJson&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="kt"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;dynamic&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;/// Add the typecast [GenericModel&amp;lt;T&amp;gt;] to fix the error&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;serializers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;deserializeWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;serializer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Serializer&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;serializer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_$genericModelSerializer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;BuiltList&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's complete the serializer class setup.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;part&lt;/span&gt; &lt;span class="s"&gt;'serializers.g.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@SerializersFor&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;Serializers&lt;/span&gt; &lt;span class="n"&gt;serializers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_$serializers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toBuilder&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addPlugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StandardJsonPlugin&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And last, let's generate the code by using the following command.&lt;br&gt;&lt;br&gt;
&lt;code&gt;dart run build_runner build&lt;/code&gt; or&lt;br&gt;&lt;br&gt;
&lt;code&gt;flutter pub run build_runner build&lt;/code&gt; if you have a Flutter project.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you get any errors with this command, try it with the following parameters:&lt;br&gt;&lt;br&gt;
&lt;code&gt;dart run build_runner build --delete-conflicting-outputs&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And we're done with the initial setup.&lt;/p&gt;
&lt;h2&gt;
  
  
  What's the problem? &lt;a id="problem"&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Now we'll test the serialization and deserialization with the generic type &lt;code&gt;String&lt;/code&gt;. We'll create the class with a list of strings and try to serialize it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;/// Testing serialization generic type [String]&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;testModel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ListBuilder&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'string 1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'string 2'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'model: &lt;/span&gt;&lt;span class="si"&gt;$testModel&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'serialized json: &lt;/span&gt;&lt;span class="si"&gt;${testModel.toJson()}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;model: GenericModel &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=[&lt;/span&gt;string 1, string 2],
&lt;span class="o"&gt;}&lt;/span&gt;
serialized json: &lt;span class="o"&gt;{&lt;/span&gt;data: &lt;span class="o"&gt;[{&lt;/span&gt;&lt;span class="nv"&gt;$:&lt;/span&gt; String, : string 1&lt;span class="o"&gt;}&lt;/span&gt;, &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$:&lt;/span&gt; String, : string 2&lt;span class="o"&gt;}]}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So this looks good. It worked.&lt;br&gt;&lt;br&gt;
But wait, we have to test deserialization as well. This won't work but don't go on my word. I'll show you.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;/// Testing serialization with generic type [String]&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;testModel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ListBuilder&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'string 1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'string 2'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'model: &lt;/span&gt;&lt;span class="si"&gt;$testModel&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'serialized json: &lt;/span&gt;&lt;span class="si"&gt;${testModel.toJson()}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;/// Testing deserialization with generic type [String]&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;dummyJson&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;'data'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'string 1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'string 2'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;testString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromJson&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyJson&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;testString&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;testString&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toJson&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Looks like it didn't work 🙃"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;model: GenericModel &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=[&lt;/span&gt;string 1, string 2],
&lt;span class="o"&gt;}&lt;/span&gt;
serialized json: &lt;span class="o"&gt;{&lt;/span&gt;data: &lt;span class="o"&gt;[{&lt;/span&gt;&lt;span class="nv"&gt;$:&lt;/span&gt; String, : string 1&lt;span class="o"&gt;}&lt;/span&gt;, &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$:&lt;/span&gt; String, : string 2&lt;span class="o"&gt;}]}&lt;/span&gt;
Looks like it didn&lt;span class="s1"&gt;'t work 🙃
Deserializing '&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;data, &lt;span class="o"&gt;[&lt;/span&gt;string 1, string 2]]&lt;span class="s1"&gt;' to '&lt;/span&gt;GenericModel&lt;span class="s1"&gt;' failed due to: Deserializing '&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;string 1, string 2]&lt;span class="s1"&gt;' to '&lt;/span&gt;BuiltList&amp;lt;Object&amp;gt;&lt;span class="s1"&gt;' failed due to: Bad state: No serializer for '&lt;/span&gt;Object&lt;span class="s1"&gt;'.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The deserialization doesn't work. It's because &lt;code&gt;built_value&lt;/code&gt; cannot detect the data type of the object to be created.&lt;br&gt;&lt;br&gt;
Hence we have to tell it explicitly.&lt;/p&gt;
&lt;h2&gt;
  
  
  Finally, a solution! &lt;a id="solution"&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;There are two things we need to add to fix this.&lt;br&gt;&lt;br&gt;
First, the &lt;code&gt;specifiedType&lt;/code&gt; and second, the &lt;code&gt;addBuilderFactory&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Adding &lt;code&gt;specifiedType&lt;/code&gt; &lt;a id="1-solution"&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;In &lt;code&gt;GenericModel&lt;/code&gt; class, we will explicitly tell the serializer to deserialize the &lt;code&gt;T&lt;/code&gt; type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GenericModel&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="n"&gt;Built&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;,&lt;/span&gt; &lt;span class="n"&gt;GenericModelBuilder&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;_&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
 &lt;span class="p"&gt;...&lt;/span&gt;

  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fromJson&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="kt"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;dynamic&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;/// &amp;lt;-------- Added here&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;serializers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;deserialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;specifiedType:&lt;/span&gt; &lt;span class="n"&gt;FullType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;FullType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)]),&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="c1"&gt;/// &amp;lt;-------- Added here&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Serializer&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;serializer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_$genericModelSerializer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;BuiltList&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before moving to step 2, let's run the code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;model: GenericModel &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=[&lt;/span&gt;string 1, string 2],
&lt;span class="o"&gt;}&lt;/span&gt;
serialized json: &lt;span class="o"&gt;{&lt;/span&gt;data: &lt;span class="o"&gt;[{&lt;/span&gt;&lt;span class="nv"&gt;$:&lt;/span&gt; String, : string 1&lt;span class="o"&gt;}&lt;/span&gt;, &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$:&lt;/span&gt; String, : string 2&lt;span class="o"&gt;}]}&lt;/span&gt;

Looks like it didn&lt;span class="s1"&gt;'t work 🙃
Deserializing '&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;data, &lt;span class="o"&gt;[&lt;/span&gt;string 1, string 2]]&lt;span class="s1"&gt;' to '&lt;/span&gt;GenericModel&amp;lt;String&amp;gt;&lt;span class="s1"&gt;' failed due to: Bad state: No builder factory for GenericModel&amp;lt;String&amp;gt;. Fix by adding one, see SerializersBuilder.addBuilderFactory.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Progress, we have a different error now.&lt;br&gt;&lt;br&gt;
The error mentions &lt;code&gt;addBuilderFactory&lt;/code&gt;, the same thing that we need for step 2.&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Adding &lt;code&gt;addBuilderFactory&lt;/code&gt; &lt;a id="2-solution"&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This will be added to the &lt;code&gt;serializer.dart&lt;/code&gt; class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="nd"&gt;@SerializersFor&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;Serializers&lt;/span&gt; &lt;span class="n"&gt;serializers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_$serializers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addPlugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StandardJsonPlugin&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="c1"&gt;/// &amp;lt;-------- Added here&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addBuilderFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;FullType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;FullType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)]),&lt;/span&gt;
        &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;GenericModelBuilder&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(),&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addBuilderFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;FullType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuiltList&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;FullType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)]),&lt;/span&gt;
        &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ListBuilder&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(),&lt;/span&gt;
      &lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="c1"&gt;/// &amp;lt;-------- Added here&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, if we run the code everything works. Yay! 🎉&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;model: GenericModel &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=[&lt;/span&gt;string 1, string 2],
&lt;span class="o"&gt;}&lt;/span&gt;
serialized json: &lt;span class="o"&gt;{&lt;/span&gt;data: &lt;span class="o"&gt;[{&lt;/span&gt;&lt;span class="nv"&gt;$:&lt;/span&gt; String, : string 1&lt;span class="o"&gt;}&lt;/span&gt;, &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$:&lt;/span&gt; String, : string 2&lt;span class="o"&gt;}]}&lt;/span&gt;
GenericModel &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=[&lt;/span&gt;string 1, string 2],
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;data: &lt;span class="o"&gt;[{&lt;/span&gt;&lt;span class="nv"&gt;$:&lt;/span&gt; String, : string 1&lt;span class="o"&gt;}&lt;/span&gt;, &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$:&lt;/span&gt; String, : string 2&lt;span class="o"&gt;}]}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  This solution works. Why? &lt;a id="reason"&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;built_value&lt;/code&gt; doesn't add a &lt;code&gt;builder&lt;/code&gt; and &lt;code&gt;specifiedType&lt;/code&gt; for generic values.&lt;br&gt;&lt;br&gt;
It is up to the developers how they want to define it.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;test&lt;/code&gt; file of the &lt;code&gt;built_value&lt;/code&gt; package, they have defined such a case &lt;a href="https://github.com/google/built_value.dart/blob/master/end_to_end_test/test/generics_nnbd_serializer_test.dart#L36" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;/// code snippet from the generics_serializer_test.dart file at line 38&lt;/span&gt;
&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'GenericValue with known specifiedType and correct builder'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GenericValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;((&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;specifiedType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;FullType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GenericValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;FullType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)]);&lt;/span&gt;

   &lt;span class="c1"&gt;/// defining a different serializer&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;serializersWithBuilder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serializers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addBuilderFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;specifiedType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;GenericValueBuilder&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()))&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;serialized&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
      &lt;span class="s"&gt;'value'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kt"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'can be serialized'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="n"&gt;serializersWithBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;serialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;specifiedType:&lt;/span&gt; &lt;span class="n"&gt;specifiedType&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="n"&gt;serialized&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'can be deserialized'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;   &lt;span class="c1"&gt;/// &amp;lt;--- using different serializer&lt;/span&gt;
      &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="n"&gt;serializersWithBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;deserialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serialized&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="nl"&gt;specifiedType:&lt;/span&gt; &lt;span class="n"&gt;specifiedType&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The deserialization is done using a custom serializer object which contains a new builder and a specified type.&lt;/p&gt;

&lt;p&gt;If we were to use generic value with collections (like &lt;code&gt;BuiltList&lt;/code&gt;) we need another builder. This is mentioned in &lt;a href="https://github.com/google/built_value.dart/blob/master/end_to_end_test/test/generics_nnbd_serializer_test.dart#L194" rel="noopener noreferrer"&gt;this&lt;/a&gt; test.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;/// code snippet from the generics_serializer_test.dart file at line 197&lt;/span&gt;
&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'CollectionGenericValue with known specifiedType and correct builder'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CollectionGenericValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;((&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;specifiedType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;FullType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CollectionGenericValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;FullType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)]);&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;serializersWithBuilder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serializers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addBuilderFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="n"&gt;specifiedType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;CollectionGenericValueBuilder&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;())&lt;/span&gt;

          &lt;span class="c1"&gt;/// adding second builder for collection&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addBuilderFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;FullType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuiltList&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;FullType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)]),&lt;/span&gt;
              &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ListBuilder&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()))&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In addition to a custom serializer, we add another &lt;code&gt;builderFactory&lt;/code&gt; for the &lt;code&gt;BuiltList&lt;/code&gt; collection.&lt;/p&gt;

&lt;p&gt;We can of course create as many customizations now as needed by adding &lt;code&gt;specifiedType&lt;/code&gt; and &lt;code&gt;builderFactory&lt;/code&gt; methods.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Refer the test file &lt;a href="https://github.com/google/built_value.dart/blob/master/end_to_end_test/test/generics_nnbd_serializer_test.dart" rel="noopener noreferrer"&gt;here&lt;/a&gt; for more examples.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Simplifying the solution &lt;a id="simplification"&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Is this the end?&lt;br&gt;&lt;br&gt;
It depends.&lt;br&gt;&lt;br&gt;
We have found the solution but imagine you have to use the &lt;code&gt;GenericModel&lt;/code&gt; class with not just one but multiple object types. We could copy-paste the builder factory to the &lt;code&gt;serializer.dart&lt;/code&gt; class, but that's a bad idea.&lt;br&gt;&lt;br&gt;
Let me show you why.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;Serializers&lt;/span&gt; &lt;span class="n"&gt;serializers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_$serializers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addPlugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StandardJsonPlugin&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

      &lt;span class="c1"&gt;/// for [String]&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addBuilderFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;FullType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;FullType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)]),&lt;/span&gt;
        &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;GenericModelBuilder&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(),&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addBuilderFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;FullType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuiltList&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;FullType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)]),&lt;/span&gt;
        &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ListBuilder&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(),&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="c1"&gt;/// for [int]&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addBuilderFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;FullType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;FullType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)]),&lt;/span&gt;
        &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;GenericModelBuilder&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(),&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addBuilderFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;FullType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuiltList&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;FullType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)]),&lt;/span&gt;
        &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ListBuilder&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(),&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;/// and so on...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Manually adding and removing them can introduce various bugs. Plus we're lazy and don't want to remember updating this.&lt;br&gt;&lt;br&gt;
Hence, we do what we do best -&amp;gt; automate it.&lt;/p&gt;

&lt;p&gt;Automate is just a buzz keyword here, we're just going to abstract adding &lt;code&gt;builderfactory&lt;/code&gt; for &lt;code&gt;GenericModel&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We'll add a new class to the &lt;code&gt;serializers.dart&lt;/code&gt; file which adds the builder factories to &lt;code&gt;serializer&lt;/code&gt; object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="nd"&gt;@SerializersFor&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="c1"&gt;/// Making this private and mutable&lt;/span&gt;
&lt;span class="n"&gt;Serializers&lt;/span&gt; &lt;span class="n"&gt;_serializers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_$_serializers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toBuilder&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addPlugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StandardJsonPlugin&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;serializers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_serializers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;/// Class to add new factories according to the type&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GenericBuilderFactory&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;/// Keeping track of the builder factories added to the serializers for type T&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GenericBuilderFactory&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_factories&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

  &lt;span class="c1"&gt;/// returning serializer if the builder factory is already added&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Serializers&lt;/span&gt; &lt;span class="n"&gt;getSerializer&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_factories&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;containsKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_serializers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;GenericBuilderFactory&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;_addFactory&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;/// Adding the builder factory&lt;/span&gt;
  &lt;span class="n"&gt;Serializers&lt;/span&gt; &lt;span class="n"&gt;_addFactory&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_factories&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;_serializers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_serializers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addBuilderFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;FullType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;FullType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)]),&lt;/span&gt;
            &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;GenericModelBuilder&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(),&lt;/span&gt;
          &lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addBuilderFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;FullType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuiltList&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;FullType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)]),&lt;/span&gt;
            &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ListBuilder&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(),&lt;/span&gt;
          &lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_serializers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we call this static method to access &lt;code&gt;serializer&lt;/code&gt; object in our &lt;code&gt;GenericModel&lt;/code&gt; class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fromJson&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="kt"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;dynamic&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;GenericBuilderFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSerializer&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;deserialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;specifiedType:&lt;/span&gt; &lt;span class="n"&gt;FullType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;FullType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)]),&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We made a lot of changes, let's make sure our old tests are still passing.&lt;br&gt;&lt;br&gt;
Run the same &lt;code&gt;builder_runner&lt;/code&gt; command and run the project with the &lt;code&gt;dart run&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;GenericModel &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=[&lt;/span&gt;string 1, string 2],
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;data: &lt;span class="o"&gt;[{&lt;/span&gt;&lt;span class="nv"&gt;$:&lt;/span&gt; String, : string 1&lt;span class="o"&gt;}&lt;/span&gt;, &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$:&lt;/span&gt; String, : string 2&lt;span class="o"&gt;}]}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Phew! The old code is working.&lt;br&gt;&lt;br&gt;
Let's try adding a test case for &lt;code&gt;int&lt;/code&gt; type to make sure it's working.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="c1"&gt;/// Testing deserialization with generic type [String]&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;dummyJson&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;'data'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'string 1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'string 2'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;testString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromJson&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyJson&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;testString&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;testString&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toJson&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Looks like it didn't work 🙃"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;/// Testing deserialization with generic type [int]&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;dummyJsonInt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;'data'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;testInt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromJson&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyJsonInt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;testInt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;testInt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toJson&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Looks like it didn't work 🙃"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;model: GenericModel &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=[&lt;/span&gt;string 1, string 2],
&lt;span class="o"&gt;}&lt;/span&gt;
serialized json: &lt;span class="o"&gt;{&lt;/span&gt;data: &lt;span class="o"&gt;[{&lt;/span&gt;&lt;span class="nv"&gt;$:&lt;/span&gt; String, : string 1&lt;span class="o"&gt;}&lt;/span&gt;, &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$:&lt;/span&gt; String, : string 2&lt;span class="o"&gt;}]}&lt;/span&gt;
GenericModel &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=[&lt;/span&gt;string 1, string 2],
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;data: &lt;span class="o"&gt;[{&lt;/span&gt;&lt;span class="nv"&gt;$:&lt;/span&gt; String, : string 1&lt;span class="o"&gt;}&lt;/span&gt;, &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$:&lt;/span&gt; String, : string 2&lt;span class="o"&gt;}]}&lt;/span&gt;
GenericModel &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=[&lt;/span&gt;1, 2],
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;data: &lt;span class="o"&gt;[{&lt;/span&gt;&lt;span class="nv"&gt;$:&lt;/span&gt; int, : 1&lt;span class="o"&gt;}&lt;/span&gt;, &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$:&lt;/span&gt; int, : 2&lt;span class="o"&gt;}]}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It worked!&lt;br&gt;&lt;br&gt;
So now we don't need to add the builder factory manually in the &lt;code&gt;serializer&lt;/code&gt; object. This one-time setup is all we need.&lt;/p&gt;
&lt;h2&gt;
  
  
  Going one step further &lt;a id="futher"&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;We've tested our &lt;code&gt;GenericModel&lt;/code&gt; with &lt;code&gt;int&lt;/code&gt; and &lt;code&gt;String&lt;/code&gt; data types. Now let's try it with a user-defined type, a new model called &lt;code&gt;MyModel&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We'll create a new model with two properties: name and id.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;part&lt;/span&gt; &lt;span class="s"&gt;'my_model.g.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyModel&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="n"&gt;Built&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MyModel&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;,&lt;/span&gt; &lt;span class="n"&gt;MyModelBuilder&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;MyModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;_&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;factory&lt;/span&gt; &lt;span class="n"&gt;MyModel&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="kt"&gt;Function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyModelBuilder&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt; &lt;span class="n"&gt;updates&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_$MyModel&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;

  &lt;span class="kt"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;dynamic&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;toJson&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;serializers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;serializeWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;serializer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kt"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;dynamic&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;MyModel&lt;/span&gt; &lt;span class="n"&gt;fromJson&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;dynamic&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;serializers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;deserializeWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;serializer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;MyModel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Serializer&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MyModel&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;serializer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_$myModelSerializer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adding this model in the &lt;code&gt;serializer.dart&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="kn"&gt;part&lt;/span&gt; &lt;span class="s"&gt;'serializers.g.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@SerializersFor&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;MyModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;--- Adding new model here&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, run the &lt;code&gt;dart run build_runner build&lt;/code&gt; command. Now that the code is generated and the errors are gone, let's test our new model.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="c1"&gt;/// Testing deserialization with generic type [MyModel]&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;dummyJsonMyModel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;'data'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'name'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'name 1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'id'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'id 1'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'name'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'name 2'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'id'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'id 2'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;testMyModel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GenericModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromJson&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MyModel&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyJsonMyModel&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'deserialized model: &lt;/span&gt;&lt;span class="si"&gt;$testMyModel&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;/// Testing serialization with generic type [MyModel]&lt;/span&gt;
  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'serialized json: &lt;/span&gt;&lt;span class="si"&gt;${testMyModel.toJson()}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;deserialized model: GenericModel &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=[&lt;/span&gt;MyModel &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;name 1,
    &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;id &lt;/span&gt;1,
  &lt;span class="o"&gt;}&lt;/span&gt;, MyModel &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;name 2,
    &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;id &lt;/span&gt;2,
  &lt;span class="o"&gt;}]&lt;/span&gt;,
&lt;span class="o"&gt;}&lt;/span&gt;
serialized json: &lt;span class="o"&gt;{&lt;/span&gt;data: &lt;span class="o"&gt;[{&lt;/span&gt;&lt;span class="nv"&gt;$:&lt;/span&gt; MyModel, name: name 1, &lt;span class="nb"&gt;id&lt;/span&gt;: &lt;span class="nb"&gt;id &lt;/span&gt;1&lt;span class="o"&gt;}&lt;/span&gt;, &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$:&lt;/span&gt; MyModel, name: name 2, &lt;span class="nb"&gt;id&lt;/span&gt;: &lt;span class="nb"&gt;id &lt;/span&gt;2&lt;span class="o"&gt;}]}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works. We've successfully created a custom deserializer for a collection generic type model in &lt;code&gt;build_value&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
We also abstracted the addition of the builder factory for each generic type.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion &lt;a id="conclusion"&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We have to create a custom serializer to deserialize the collection of generic data-type objects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;specifiedType&lt;/code&gt; and &lt;code&gt;buildFactory&lt;/code&gt; methods have to be added for all the generic types.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The solution can be simplified by adding the above dependencies in the code instead of doing it manually.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final Note &lt;a id="final-note"&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Thank you for reading this article. If you enjoyed it, consider sharing it with other people.&lt;br&gt;&lt;br&gt;
If you find any mistakes, please let me know.&lt;br&gt;&lt;br&gt;
Feel free to share your opinions below.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>dart</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>State Persistence Techniques for the Flutter Bottom Navigation Bar</title>
      <dc:creator>Nikki Goel</dc:creator>
      <pubDate>Tue, 05 Apr 2022 07:35:35 +0000</pubDate>
      <link>https://dev.to/nicks101/state-persistence-techniques-for-the-flutter-bottom-navigation-bar-3ikc</link>
      <guid>https://dev.to/nicks101/state-persistence-techniques-for-the-flutter-bottom-navigation-bar-3ikc</guid>
      <description>&lt;p&gt;Building a bottom navigation bar is simple in Flutter given the &lt;a href="https://api.flutter.dev/flutter/material/BottomNavigationBar-class.html" rel="noopener noreferrer"&gt;BottomNavigationBar Widget&lt;/a&gt;. However, we want to add features to the standard Widget. &lt;/p&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
Setup

&lt;ul&gt;
&lt;li&gt;What do we want to achieve?&lt;/li&gt;
&lt;li&gt;Implementation&lt;/li&gt;
&lt;li&gt;Demo&lt;/li&gt;
&lt;li&gt;Result&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

1. Stack and OffStage

&lt;ul&gt;
&lt;li&gt;Implementation&lt;/li&gt;
&lt;li&gt;Demo&lt;/li&gt;
&lt;li&gt;Result&lt;/li&gt;
&lt;li&gt;Alternative - Indexed Stack&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

2. AutomaticKeepAliveClientMixin

&lt;ul&gt;
&lt;li&gt;Implementation&lt;/li&gt;
&lt;li&gt;Demo&lt;/li&gt;
&lt;li&gt;Result&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Conclusion&lt;/li&gt;

&lt;li&gt;Final Note&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;We'll set up a basic flutter app with bottom navigation and look at the problems we face. Like not initializing the bottom navigation bar pages every time we switch tabs or preserving the state of bottom tab pages.&lt;br&gt;&lt;br&gt;
Then we'll try a couple of approaches for resolving them. We'll compare the results and we can decide which one to go forward with.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Here's the &lt;a href="https://github.com/nicks101/flutter_tutorials/tree/main/preserve_state_tabs" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt; with all the code.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Setup &lt;a id="setup"&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;We're going to start with the basic app containing bottom navigation with two tabs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tab 1&lt;/strong&gt;: Scrollable list of items.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tab 2&lt;/strong&gt;: Displaying the escaped seconds of a Timer.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  What do we want to achieve? &lt;a id="goals"&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Create the navigation bar page only when we open the page.&lt;/li&gt;
&lt;li&gt;Preserve scroll position of navigation bar page in &lt;strong&gt;Tab 1&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Preserve the escaped time of Timer in &lt;strong&gt;Tab 2&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Implementation &lt;a id="setup-implementation"&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Let's start with a new Flutter project.  &lt;/p&gt;
&lt;h4&gt;
  
  
  Parent Widget: Bottom navigation bar
&lt;/h4&gt;

&lt;p&gt;We have a simple &lt;code&gt;Scaffold&lt;/code&gt; with &lt;code&gt;BottomNavigationBar&lt;/code&gt; containing two &lt;code&gt;Tabs&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BasicBottomNavigation&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatefulWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;BasicBottomNavigation&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;key:&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BasicBottomNavigation&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;createState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_BasicBottomNavigationState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;_BasicBottomNavigationState&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BasicBottomNavigation&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;currentIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;         &lt;span class="c1"&gt;/// List of tab page widgets&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;_Tabbar1&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;     
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;_Tabbar2&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;currentIndex&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="nl"&gt;bottomNavigationBar:&lt;/span&gt; &lt;span class="n"&gt;BottomNavigationBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;currentIndex:&lt;/span&gt; &lt;span class="n"&gt;currentIndex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;onTap:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;currentIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;     &lt;span class="c1"&gt;/// Switching tabs&lt;/span&gt;
          &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="nl"&gt;items:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="n"&gt;BottomNavigationBarItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;icon:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nl"&gt;label:&lt;/span&gt; &lt;span class="s"&gt;"Tab"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="n"&gt;BottomNavigationBarItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;icon:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nl"&gt;label:&lt;/span&gt; &lt;span class="s"&gt;"Tab"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Tab 1: A scrollable list of items
&lt;/h4&gt;

&lt;p&gt;We have a &lt;code&gt;ListView&lt;/code&gt; displaying the index inside a &lt;code&gt;ListTile&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;_Tabbar1&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatelessWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;_Tabbar1&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;key:&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Tabbar 1 build"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;appBar:&lt;/span&gt; &lt;span class="n"&gt;AppBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Tab bar 1"&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
      &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;ListView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;itemBuilder:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ListTile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${index + 1}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="nl"&gt;itemCount:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Tab 2: Displaying escaped seconds of a Timer
&lt;/h4&gt;

&lt;p&gt;We are using a &lt;a href="https://api.flutter.dev/flutter/scheduler/Ticker-class.html" rel="noopener noreferrer"&gt;Ticker&lt;/a&gt; to run the Timer and update our escaped duration every second. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Fun Fact:&lt;/strong&gt; Ticker is used in Flutter for callbacks during &lt;a href="https://api.flutter.dev/flutter/animation/Animation-class.html" rel="noopener noreferrer"&gt;Animation&lt;/a&gt; frames.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;_Tabbar2&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatefulWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;_Tabbar2&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;key:&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;_Tabbar2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;createState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_Tabbar2State&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;_Tabbar2State&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;_Tabbar2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;SingleTickerProviderStateMixin&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;late&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;Ticker&lt;/span&gt; &lt;span class="n"&gt;_ticker&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;Duration&lt;/span&gt; &lt;span class="n"&gt;_escapedDuration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;zero&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;escapedSeconds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_escapedDuration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;inSeconds&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;initState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;initState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Tabbar 2 initState"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;_ticker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;createTicker&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;elapsed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;elapsed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;inSeconds&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;_escapedDuration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;inSeconds&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;_escapedDuration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;elapsed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="n"&gt;_ticker&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;dispose&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_ticker&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;dispose&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;dispose&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;appBar:&lt;/span&gt; &lt;span class="n"&gt;AppBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Tab bar 2"&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
      &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;Center&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;escapedSeconds&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Demo &lt;a id="setup-demo"&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx5cgu1mvkc6bxe0al8s7.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx5cgu1mvkc6bxe0al8s7.gif" alt="demo_01.gif" width="438" height="816"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Result &lt;a id="setup-result"&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Tabs are initialized only when we click on them.
&lt;/li&gt;
&lt;li&gt;The scroll position is &lt;strong&gt;not&lt;/strong&gt; preserved.&lt;/li&gt;
&lt;li&gt;Escaped time of the Timer is &lt;strong&gt;not&lt;/strong&gt; preserved.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Nothing was preserved. We create new tab pages every time we click on them. The scroll position is lost we switch back to &lt;code&gt;Tab 1&lt;/code&gt;. The Timer starts from 0 whenever we open &lt;code&gt;Tab 2&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;There is no problem with this approach as long as we don't need to preserve any state.&lt;br&gt;&lt;br&gt;
But since we do, let's look at how we can achieve it.&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Stack and OffStage &lt;a id="1-stack"&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;One way to persist the bottom navigation bar page is to use &lt;a href="https://api.flutter.dev/flutter/widgets/Stack-class.html" rel="noopener noreferrer"&gt;Stack&lt;/a&gt; Widget.&lt;br&gt;
We'll add all the pages as children of &lt;code&gt;Stack&lt;/code&gt; with the order of the bottom tabs and display one child at a time with respect to the currently selected bottom tab.&lt;/p&gt;
&lt;h3&gt;
  
  
  Implementation &lt;a id="1-stack-implementation"&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;We'll wrap the &lt;code&gt;Tabbar&lt;/code&gt; widgets with &lt;a href="https://api.flutter.dev/flutter/widgets/Stack-class.html" rel="noopener noreferrer"&gt;OffStage&lt;/a&gt; and the children list with &lt;code&gt;Stack&lt;/code&gt;.&lt;br&gt;
The offstage parameter takes a boolean value. If it's true, then the child is &lt;code&gt;hidden&lt;/code&gt; or &lt;code&gt;offstage&lt;/code&gt;, otherwise, the child is visible.&lt;br&gt;&lt;br&gt;
There is no change in the Tabbar classes.&lt;/p&gt;
&lt;h4&gt;
  
  
  Parent Widget: Bottom navigation bar
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Scaffold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;       &lt;span class="c1"&gt;///  Added Stack Widget&lt;/span&gt;
        &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="n"&gt;Offstage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;          &lt;span class="c1"&gt;/// Wrap Tab with OffStage &lt;/span&gt;
            &lt;span class="nl"&gt;offstage:&lt;/span&gt; &lt;span class="n"&gt;currentIndex&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;_Tabbar1&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
          &lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="n"&gt;Offstage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;offstage:&lt;/span&gt; &lt;span class="n"&gt;currentIndex&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;_Tabbar2&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
          &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Demo &lt;a id="1-stack-demo"&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuj9qkm4rkyl114tyaa29.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuj9qkm4rkyl114tyaa29.gif" alt="demo_02.gif" width="438" height="816"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Result &lt;a id="1-stack-result"&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Tabs are &lt;strong&gt;not&lt;/strong&gt; initialized only when we click on them.
&lt;/li&gt;
&lt;li&gt;The scroll position is preserved.&lt;/li&gt;
&lt;li&gt;Escaped time of the Timer is preserved.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All the tabs are initialized with the parent Widget. Hence the timer in &lt;code&gt;Tabbar 2&lt;/code&gt; started before we even opened that Tab. The good thing is that it preserves the scroll position and escaped time.&lt;/p&gt;

&lt;p&gt;If creating all the tabs at once does not affect the performance and is what we want, then we use this technique.&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Alternative - Indexed Stack &lt;a id="1-stack-alternative"&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Turns out there's a &lt;code&gt;Widget&lt;/code&gt; (as always with Flutter 😇) called &lt;a href="https://api.flutter.dev/flutter/widgets/IndexedStack-class.html" rel="noopener noreferrer"&gt;IndexedStack&lt;/a&gt; that we can use. It's less code with the same result.&lt;/p&gt;
&lt;h4&gt;
  
  
  Parent Widget: Bottom navigation bar
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Scaffold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;IndexedStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;      &lt;span class="c1"&gt;/// Replaced with IndexedStack&lt;/span&gt;
        &lt;span class="nl"&gt;index:&lt;/span&gt; &lt;span class="n"&gt;currentIndex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="n"&gt;_Tabbar1&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
          &lt;span class="n"&gt;_Tabbar2&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  2. AutomaticKeepAliveClientMixin &lt;a id="2-mixin"&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;As the name suggests, this mixin makes the client (Tabbar child widgets) keep themselves alive (not disposed of) after we switch the tabs. It also creates the Tab only when it is first clicked and not with the Parent Widget like the above methods.&lt;/p&gt;
&lt;h3&gt;
  
  
  Implementation &lt;a id="2-mixin-implementation"&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;AutomaticKeepAliveClientMixin needs a &lt;a href="https://api.flutter.dev/flutter/widgets/PageView-class.html" rel="noopener noreferrer"&gt;PageView&lt;/a&gt; in the parent widget. So we'll wrap the body with PageView and pass the list of tabs as its children.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Further Reading:&lt;/strong&gt; Other than PageView, there's a &lt;a href="https://api.flutter.dev/flutter/material/TabBarView-class.html" rel="noopener noreferrer"&gt;TabBarView&lt;/a&gt; (for top app bar tabs), which also makes AutomaticKeepAliveClientMixin work for tabs (child widgets) because it uses PageView internally.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;
  
  
  Parent Widget: Bottom navigation bar
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AliveMixinDemo&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatefulWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;AliveMixinDemo&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;key:&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AliveMixinDemo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;createState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_AliveMixinDemoState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;_AliveMixinDemoState&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AliveMixinDemo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;PageController&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PageController&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;/// initializing controller for PageView&lt;/span&gt;

  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;currentIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;tabPages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;_Tabbar1&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;_Tabbar2&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;PageView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;        &lt;span class="c1"&gt;/// Wrapping the tabs with PageView&lt;/span&gt;
        &lt;span class="nl"&gt;controller:&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="n"&gt;tabPages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;onPageChanged:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;currentIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;     &lt;span class="c1"&gt;/// Switching bottom tabs&lt;/span&gt;
          &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;bottomNavigationBar:&lt;/span&gt; &lt;span class="n"&gt;BottomNavigationBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;currentIndex:&lt;/span&gt; &lt;span class="n"&gt;currentIndex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;onTap:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jumpToPage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;    &lt;span class="c1"&gt;/// Switching the PageView tabs&lt;/span&gt;
          &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;currentIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="nl"&gt;items:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="n"&gt;BottomNavigationBarItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;icon:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nl"&gt;label:&lt;/span&gt; &lt;span class="s"&gt;"Tab"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="n"&gt;BottomNavigationBarItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;icon:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nl"&gt;label:&lt;/span&gt; &lt;span class="s"&gt;"Tab"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Tab 1: A scrollable list of items
&lt;/h4&gt;

&lt;p&gt;We replacing to &lt;code&gt;StatefulWidget&lt;/code&gt; here because &lt;code&gt;AutomaticKeepAliveClientMixin&lt;/code&gt; only works with the &lt;code&gt;State&lt;/code&gt; Class as defined in its &lt;a href="https://api.flutter.dev/flutter/widgets/AutomaticKeepAliveClientMixin-mixin.html" rel="noopener noreferrer"&gt;implementation&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"A mixin with convenience methods for clients of AutomaticKeepAlive. Used with State subclasses."  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We need only two additions after this.&lt;br&gt;&lt;br&gt;
First, call the &lt;code&gt;super.build()&lt;/code&gt; inside the build method. Second, override the &lt;code&gt;wantKeepAlive&lt;/code&gt; and return &lt;code&gt;true&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;_Tabbar1&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatefulWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;_Tabbar1&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;key:&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;_Tabbar1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;createState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_Tabbar1State&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;_Tabbar1State&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;_Tabbar1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; 
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;AutomaticKeepAliveClientMixin&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;     &lt;span class="c1"&gt;/// Using the mixin&lt;/span&gt;
  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;    &lt;span class="c1"&gt;/// Calling build method of mixin&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Tabbar 1 build"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;appBar:&lt;/span&gt; &lt;span class="n"&gt;AppBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Tab bar 1"&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
      &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;ListView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;itemBuilder:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ListTile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${index + 1}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="nl"&gt;itemCount:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;wantKeepAlive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c1"&gt;/// Overriding the value to preserve the state&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Tab 2: Displaying escaped seconds of a Timer
&lt;/h4&gt;

&lt;p&gt;The changes are the same as with the &lt;code&gt;Tabbar 1&lt;/code&gt; class above.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;_Tabbar2State&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;_Tabbar2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;SingleTickerProviderStateMixin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;AutomaticKeepAliveClientMixin&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;    &lt;span class="c1"&gt;/// Using the mixin&lt;/span&gt;
  &lt;span class="kd"&gt;late&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;Ticker&lt;/span&gt; &lt;span class="n"&gt;_ticker&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;     &lt;span class="c1"&gt;/// Calling build method of mixin&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;appBar:&lt;/span&gt; &lt;span class="n"&gt;AppBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Tab bar 2"&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
      &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;Center&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;escapedSeconds&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;wantKeepAlive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;/// Overriding the value to preserve the state&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Demo &lt;a id="2-mixin-demo"&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuqch1xgua2hghmphzv1s.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuqch1xgua2hghmphzv1s.gif" alt="demo_03.gif" width="456" height="744"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Result &lt;a id="2-mixin-result"&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Tabs are initialized only when we click on them.
&lt;/li&gt;
&lt;li&gt;The scroll position is preserved.&lt;/li&gt;
&lt;li&gt;Escaped time of the Timer is preserved.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The &lt;code&gt;Tabbar 2&lt;/code&gt; is initialized only the first time when we click on it. The Timer preserves its state and so does the scrolling position in &lt;code&gt;Tabbar 1&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If we want to programmatically change the &lt;code&gt;keepAlive&lt;/code&gt; condition, then we can use the &lt;code&gt;updateKeepAlive()&lt;/code&gt; method of &lt;code&gt;AutomaticKeepAliveClientMixin&lt;/code&gt;. For further reading, refer to &lt;a href="https://stackoverflow.com/a/67618563/9468577" rel="noopener noreferrer"&gt;this&lt;/a&gt; StackOverflow answer.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Conclusion &lt;a id="conclusion"&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;We can choose any one approach from the above options according to our requirements. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Don't want to preserve any state -&amp;gt; standard &lt;code&gt;BottomBarNavigation&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Want to preserve state but fine with creating all the tabs at once -&amp;gt; &lt;code&gt;IndexedStack&lt;/code&gt; or &lt;code&gt;Stack and OffStage&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Want to preserve state and build tabs only once when clicked on them -&amp;gt; &lt;code&gt;AutomaticKeepAliveClientMixin&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;IndexedStack&lt;/code&gt; is the simplest approach while &lt;code&gt;AutomaticKeepAliveClientMixin&lt;/code&gt; covers our need. Since we usually have API calls in tabs and don't want to call them every time we switch to that tab.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Final Note &lt;a id="final-note"&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Thank you for reading this article. If you enjoyed it, consider sharing it with other people.&lt;br&gt;&lt;br&gt;
If you find any mistakes, please let me know.&lt;br&gt;&lt;br&gt;
Feel free to share your opinions below.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>mobile</category>
      <category>tutorial</category>
      <category>learning</category>
    </item>
    <item>
      <title>Improve Flutter Skills by Studying Production-Level Applications</title>
      <dc:creator>Nikki Goel</dc:creator>
      <pubDate>Fri, 22 Oct 2021 07:11:23 +0000</pubDate>
      <link>https://dev.to/nicks101/improve-flutter-skills-by-studying-production-level-applications-57oh</link>
      <guid>https://dev.to/nicks101/improve-flutter-skills-by-studying-production-level-applications-57oh</guid>
      <description>&lt;p&gt;There are many concepts to understand in mobile development. Among these are pagination in API requests, local storage, error reporting, debugging, testing, linting, and CI/CD.&lt;/p&gt;

&lt;p&gt;Following is a list of some open-source Flutter projects that can be used to study and improve our skills. All of these projects offer some useful concepts we can learn from.&lt;/p&gt;

&lt;h2&gt;
  
  
  Goal
&lt;/h2&gt;

&lt;p&gt;We can learn from other people's code to understand and implement better code ourselves. This is where open-source projects come in. Using open-source projects is one of the best ways to improve our skills.  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I look up to them personally. The list could have been much longer, but here I listed a few to get you started. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's take a look.&lt;/p&gt;




&lt;h3&gt;
  
  
  1. &lt;a href="https://github.com/flutter/photobooth" rel="noopener noreferrer"&gt;Photobooth&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This is a web app. Flutter Web was made available on the stable channel this year. So Photo Booth is a great example of flutter web apps.&lt;br&gt;&lt;br&gt;
Another thing to learn from this is the use of &lt;strong&gt;native plugins&lt;/strong&gt; like cameras. There're also &lt;strong&gt;firebase&lt;/strong&gt; packages like firebase authentication, firebase storage, etc.&lt;/p&gt;

&lt;p&gt;The app shows how we can &lt;strong&gt;internationalize&lt;/strong&gt; a flutter app, how to structure folders, and the use of &lt;strong&gt;bloc&lt;/strong&gt; as state management.&lt;/p&gt;

&lt;p&gt;To go one step ahead, there's also CI/CD to look at when working with the deployment part. This app has &lt;strong&gt;GitHub workflows&lt;/strong&gt; for testing, analyzing lint rules, deploying the new app version, etc.&lt;/p&gt;

&lt;p&gt;The main focus for me though is the &lt;strong&gt;tests&lt;/strong&gt; folder. From mocking a library to test gestures, there are many test cases that we can learn from.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. &lt;a href="https://github.com/mhadaily/pluralsight-debugging-testing-publishing-flutter-app" rel="noopener noreferrer"&gt;Debugging Testing Publishing Flutter App&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This app is a part of a &lt;a href="https://www.pluralsight.com/courses/debugging-testing-publishing-flutter-app" rel="noopener noreferrer"&gt;course&lt;/a&gt;. There are different branches for each topic.&lt;/p&gt;

&lt;p&gt;As the name suggests, we can learn about error reporting, testing (unit, widget, and integration tests), and debugging.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. &lt;a href="https://github.com/rrousselGit/river_pod/tree/master/examples/marvel" rel="noopener noreferrer"&gt;Marvel&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This is specifically for &lt;a href="https://riverpod.dev/" rel="noopener noreferrer"&gt;riverpod&lt;/a&gt; package.&lt;br&gt;&lt;br&gt;
This app shows how we can paginate API requests while scrolling, how to cancel a request, and cache the result.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. &lt;a href="https://github.com/bizz84/movie_app_state_management_flutter" rel="noopener noreferrer"&gt;Movie App State Management Flutter&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This project is wonderful. It shows how we can structure our code with various &lt;strong&gt;state management&lt;/strong&gt; packages.&lt;/p&gt;

&lt;p&gt;In addition to pagination, there's &lt;strong&gt;local data persistence&lt;/strong&gt; as well.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. &lt;a href="https://github.com/funwithflutter/riverpod_tutorials" rel="noopener noreferrer"&gt;Riverpod Tutorials&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This project is specifically for &lt;a href="https://riverpod.dev/" rel="noopener noreferrer"&gt;riverpod&lt;/a&gt; package.&lt;br&gt;&lt;br&gt;
This is a ToDo application. The project starts simple with basic functionality and then progresses with new features. There is a different folder for each concept.  &lt;/p&gt;

&lt;p&gt;This project first introduces various providers. Then it shows how we can use them to pass data in our UI. Next comes how to deal with asynchronous data with Riverpod. There's error handling and cache management as well.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. &lt;a href="https://github.com/flutter/flutter/tree/master/examples" rel="noopener noreferrer"&gt;Flutter Templates&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;These are the templates/examples from the Flutter team. From "hello world" to "flutter layer architecture" and "platform channel", there is a lot to cover.&lt;br&gt;&lt;br&gt;
This is great for getting started.  &lt;/p&gt;

&lt;p&gt;Additionally, there's another project with templates, &lt;a href="https://github.com/brianegan/new_flutter_template" rel="noopener noreferrer"&gt;new_flutter_template&lt;/a&gt;. This one is still in work in progress I believe. But there are a few samples to look at.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. &lt;a href="https://github.com/flutter/gallery" rel="noopener noreferrer"&gt;Gallery&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This app shows a number of examples of different widgets. &lt;br&gt;
Besides that, the source code itself is a great example of how to deal with different themes, including font size and locale.  &lt;/p&gt;

&lt;p&gt;In addition to learning how to build the UI, there are also tests, Github workflows, and linting to look at.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. &lt;a href="https://github.com/bizz84/starter_architecture_flutter_firebase" rel="noopener noreferrer"&gt;Starter Architecture Flutter Firebase&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This project focuses on the architecture and folder structure of the source code.&lt;br&gt;&lt;br&gt;
There is a lot of thought given to building a big-scale app codebase.&lt;/p&gt;

&lt;p&gt;For state management and backend it's using Riverpod and firebase respectively. The common functionalities signing up, using firebase storage, dealing with APIs and streams, etc are converted with tests.&lt;/p&gt;

&lt;p&gt;The other thing I appreciate about this project is the use of &lt;strong&gt;linting&lt;/strong&gt;. Although now with the latest Flutter version, linting comes by default when we create a new app.&lt;br&gt;&lt;br&gt;
Nonetheless, linting is always a good thing to implement in a project.&lt;/p&gt;

&lt;p&gt;There are some features/widgets that we might use in more than one app like a fancy animating container. We can make this code reusable if we make a separate &lt;strong&gt;package&lt;/strong&gt; for it and import it into the projects that require it.&lt;br&gt;&lt;br&gt;
The author of this project does this for many UI components (widgets) and certain services like firebase auth. Now whenever the author has to use Firebase authentication, he can simply import the package and save time.  &lt;/p&gt;

&lt;p&gt;From studying this project can learn how to create a customizable and independent feature or services into a package.&lt;/p&gt;

&lt;h3&gt;
  
  
  9. &lt;a href="https://github.com/jesusrp98/spacex-go" rel="noopener noreferrer"&gt;SpaceX Go&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This project seems to have it all. It handles API requests, caching images, managing notifications, localization, navigation, slivers, etc.&lt;/p&gt;

&lt;p&gt;The beauty of this codebase is the code reusability. The project has a well-defined structure and uses &lt;a href="https://dart.dev/guides/language/language-tour#generics" rel="noopener noreferrer"&gt;generic classes&lt;/a&gt;.&lt;br&gt;&lt;br&gt;
This project can also be used to learn how to create model classes. Other things to look out for are tests, linting, and Github workflows.&lt;/p&gt;

&lt;p&gt;Overall, the code is beautifully written and the project is well structured.  &lt;/p&gt;

&lt;h3&gt;
  
  
  10. &lt;a href="https://github.com/tvolkert/chicago" rel="noopener noreferrer"&gt;Chicago&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Ever wanted to make your own widgets from scratch? By scratch here, I mean the &lt;a href="https://api.flutter.dev/flutter/rendering/RenderObject-class.html" rel="noopener noreferrer"&gt;RenderObject&lt;/a&gt; itself.&lt;/p&gt;

&lt;p&gt;There is rarely a need for someone to create your own render objects, but when the need arrives we can refer to this project to understand how to create them.&lt;br&gt;&lt;br&gt;
There're also tests written for these widgets.&lt;/p&gt;

&lt;h3&gt;
  
  
  11. &lt;a href="https://github.com/ResoCoder/finished-flutter-firebase-ddd-course" rel="noopener noreferrer"&gt;Finished Flutter Firebase DDD Course&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;With application architecture patterns in mind, the Domain-Driven Design pattern is one of the patterns we should be familiar with. This project follows the DDD architecture pattern and has tutorial series with both &lt;a href="https://resocoder.com/category/tutorials/flutter/firebase-ddd" rel="noopener noreferrer"&gt;articles&lt;/a&gt; and &lt;a href="https://www.youtube.com/watch?v=RMiN59x3uH0&amp;amp;list=PLB6lc7nQ1n4iS5p-IezFFgqP6YvAJy84U&amp;amp;ab_channel=ResoCoder" rel="noopener noreferrer"&gt;videos&lt;/a&gt; by the author.&lt;/p&gt;

&lt;p&gt;Along with DDD, the author has another &lt;a href="https://github.com/ResoCoder/flutter-tdd-clean-architecture-course" rel="noopener noreferrer"&gt;application&lt;/a&gt; and &lt;a href="https://resocoder.com/flutter-clean-architecture-tdd" rel="noopener noreferrer"&gt;tutorial series&lt;/a&gt; for Clean Architecture + Test-Driven Development (TDD).&lt;/p&gt;

&lt;h3&gt;
  
  
  12. &lt;a href="https://github.com/dart-lang/sdk/tree/main/samples/ffi/sqlite" rel="noopener noreferrer"&gt;Sqlite&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;To learn how to interact and write with the native interface (C APIs) in the dart, also known as &lt;a href="https://dart.dev/guides/libraries/c-interop" rel="noopener noreferrer"&gt;ffi&lt;/a&gt;, this project is a great example.&lt;br&gt;&lt;br&gt;
As a bonus, there are tests as well.&lt;/p&gt;

&lt;h3&gt;
  
  
  13. &lt;a href="https://github.com/vandadnp/flutter-tips-and-tricks" rel="noopener noreferrer"&gt;Flutter Tips and Tricks&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This is not a flutter application but a repository with a collection of various flutter/dart code snippets.&lt;br&gt;&lt;br&gt;
Nonetheless, the collection is amazing and a great learning tool. There are various small tricks for optimization and such as well.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Note
&lt;/h2&gt;

&lt;p&gt;Thank you for reading this article. If you enjoyed it, consider sharing it with other people.&lt;br&gt;
If you find any mistakes, please let me know.&lt;br&gt;
Feel free to share your opinions below.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>mobile</category>
      <category>resources</category>
      <category>learning</category>
    </item>
    <item>
      <title>Reasons to learn Computer Networking as a Software Engineer</title>
      <dc:creator>Nikki Goel</dc:creator>
      <pubDate>Tue, 07 Sep 2021 12:09:58 +0000</pubDate>
      <link>https://dev.to/nicks101/reasons-to-learn-computer-networking-as-a-software-engineer-44l9</link>
      <guid>https://dev.to/nicks101/reasons-to-learn-computer-networking-as-a-software-engineer-44l9</guid>
      <description>&lt;p&gt;Listed below are the reasons why you might consider studying Computer Networking. It doesn't matter what your specialization is.&lt;br&gt;&lt;br&gt;
These are my personal opinions and reasons why I find this subject fascinating even though I don't directly work on it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: You don't have to be an expert in Computer Networks, just knowing the basics gives an edge. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are in no particular order.&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Clear up misconceptions
&lt;/h2&gt;

&lt;p&gt;Since we don't work in the networking field directly, we make some assumptions about how things might work. In fact, even the most basic terms that we ourselves daily use can be wrong.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For a long time, I thought that the source port is the same as the destination port in a network packet header. All the concepts that depended on this misconception were also erroneously assumed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Our misconceptions might even be unknown to us until someone challenges them. So challenge yourself and question everything. Be curious.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Unravel technical terms we encounter every day
&lt;/h2&gt;

&lt;p&gt;There are certain terms that we often hear like routers, web servers, proxy, etc. If we invest time to understand these, it will help us gain a better understanding of the overall perspective.&lt;br&gt;
We don't have to deep dive into them, but the concept behind them should be clear.&lt;/p&gt;

&lt;p&gt;We're not just improving our vocabulary, but we're also understanding the meaning of the words as we use them in our conversations.&lt;/p&gt;
&lt;h2&gt;
  
  
  3. Visualize the "Big Picture": Information traveling around the world
&lt;/h2&gt;

&lt;p&gt;An API request like the below one seems simple at first look.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But if we start unfolding it, it might take hours to understand the whole path.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An oversimplification would be like this:&lt;br&gt;&lt;br&gt;
Tracking the layers of TCP/IP model -&amp;gt; routers -&amp;gt; remote server somewhere in the world -&amp;gt; back to us  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Just connecting all these dots reveals the "Big Picture". &lt;/p&gt;

&lt;center&gt;
![how-internet-works-1.png](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2py04ni08kzd6ct0okre.png)
Source: [Standford](https://web.stanford.edu/class/msande91si/www-spr04/readings/week1/InternetWhitepaper.htm)
&lt;/center&gt;

&lt;p&gt;Now every time we work on a problem, subconsciously we'll think about it from a Computer Networking perspective as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. History as viewed through the lens of Networking
&lt;/h2&gt;

&lt;p&gt;The more I research computer networking, the more interested I become in its history.    &lt;/p&gt;

&lt;p&gt;I started with "How the internet works" and now I'm mapping together how HTTP came into the picture, its evolution from HTTP/1 to HTTP/3. &lt;/p&gt;

&lt;p&gt;The questions like "Why does this tech exist?" and "What problems did it solve?" unravel the dilemma of which tech to use in what situations.&lt;br&gt;
And this knowledge comes with practice as well as from knowing its history.&lt;/p&gt;

&lt;p&gt;I'm amazed how Computer Networking is evolving and yet it's using the same principles.&lt;/p&gt;




&lt;p&gt;If any of these reasons convinced you to dive into computer networks, what were they? I'd love to hear any additional reasons that you might add to this list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Note
&lt;/h2&gt;

&lt;p&gt;Thank you for reading this article. If you enjoyed it, consider sharing it with other people.&lt;br&gt;
If you find any mistakes, please let me know.&lt;br&gt;
Feel free to share your opinions below.&lt;/p&gt;

</description>
      <category>networking</category>
      <category>computerscience</category>
      <category>learning</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Future in dart: When to use async, await, and then</title>
      <dc:creator>Nikki Goel</dc:creator>
      <pubDate>Sat, 07 Aug 2021 05:45:35 +0000</pubDate>
      <link>https://dev.to/nicks101/future-in-dart-when-to-use-async-await-and-then-2bo9</link>
      <guid>https://dev.to/nicks101/future-in-dart-when-to-use-async-await-and-then-2bo9</guid>
      <description>&lt;p&gt;There are multiple ways to implement asynchronous logic in dart. Dart provides three keywords for this: &lt;code&gt;async&lt;/code&gt;, &lt;code&gt;await&lt;/code&gt;, and &lt;code&gt;then&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
In this blog, we'll learn how and when to use them according to our needs.&lt;/p&gt;
&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;What is asynchronous programming?&lt;/li&gt;
&lt;li&gt;Asynchronous in dart&lt;/li&gt;
&lt;li&gt;Using &lt;code&gt;then&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Using &lt;code&gt;async-await&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
Code Samples

&lt;ul&gt;
&lt;li&gt;Sample 1&lt;/li&gt;
&lt;li&gt;Sample 2&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;li&gt;Final Note&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  What is asynchronous programming? &lt;a id="asynchronous-programming"&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Asynchronous programming refers to a block of code that runs in parallel with other blocks of code. As a result, we can do several things at the same time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/QX15lZJbifeQPzcNDt/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/QX15lZJbifeQPzcNDt/giphy.gif" width="384" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://giphy.com/gifs/monday-computer-molehill-QX15lZJbifeQPzcNDt" rel="noopener noreferrer"&gt;GIPHY&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example, say we have an API request that fetches a list of recipes. This network call might take some time. During this fetching, we have a text field where a user can type into.&lt;br&gt;&lt;br&gt;
Our application is interacting with the user as well as fetching recipes simultaneously.&lt;br&gt;&lt;br&gt;
Another way to think about this is, doing some background tasks separately without disrupting the main task flow.&lt;/p&gt;
&lt;h2&gt;
  
  
  Asynchronous in dart &lt;a id="asynchronous-in-dart"&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Dart gives us two ways to implement asynchronous logic: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://api.flutter.dev/flutter/dart-async/Stream-class.html" rel="noopener noreferrer"&gt;Stream&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://api.flutter.dev/flutter/dart-async/Future-class.html" rel="noopener noreferrer"&gt;Future&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this blog, we'll discuss &lt;code&gt;Future&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
&lt;code&gt;Future&lt;/code&gt; class has various constructors that we can use. There are certain keywords that we need to implement when using them. The keywords are: &lt;code&gt;async&lt;/code&gt;, &lt;code&gt;await&lt;/code&gt;, and &lt;code&gt;then&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Using &lt;code&gt;then&lt;/code&gt; &lt;a id="using-then"&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;then&lt;/code&gt; works on the concept of callbacks. The callback is exactly what it says it is. Calling back (executing) a block of code sometime later.  &lt;/p&gt;

&lt;p&gt;Let's say we are fetching a list of recipes. This returns a &lt;code&gt;Future&lt;/code&gt;.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After the &lt;code&gt;Future&lt;/code&gt; is completed (we've fetched the recipes), we want to display a message to the user.
&lt;/li&gt;
&lt;li&gt;During this fetching, we don't want to stick there but continue to execute our next block of code.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's look at the following code. For simplicity, we'll use print statements. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can run the code sample below in &lt;a href="https://dartpad.dev/" rel="noopener noreferrer"&gt;dartpad&lt;/a&gt;. Just copy-paste the code in dartpad and run it.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="n"&gt;fetching&lt;/span&gt; &lt;span class="n"&gt;recipes&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt; &lt;span class="n"&gt;computation&lt;/span&gt;
&lt;span class="n"&gt;recipes&lt;/span&gt; &lt;span class="n"&gt;fetched&lt;/span&gt;
&lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="n"&gt;fetching&lt;/span&gt; &lt;span class="n"&gt;recipes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Let's understand the code.  &lt;/p&gt;

&lt;p&gt;In line 4, we are fetching our recipes.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Here, we've used the &lt;code&gt;Future.delayed&lt;/code&gt; constructor for demo purposes. Using this, we can specify the time we want to wait for (here we are waiting for 1 second).&lt;br&gt;
Refer &lt;a href="https://api.flutter.dev/flutter/dart-async/Future/Future.delayed.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;, if you want to know more about this function.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In lines 6-8, we are giving a callback (a block of code) that is supposed to run when the recipes are fetched (or &lt;code&gt;Future&lt;/code&gt; is completed).&lt;br&gt;&lt;br&gt;
The code after line 8 should not wait for the recipes to be fetched but continue to execute.&lt;/p&gt;

&lt;p&gt;Analyzing the output:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The first console print statement is &lt;code&gt;start fetching recipes&lt;/code&gt; as expected.
&lt;/li&gt;
&lt;li&gt;The second console print statement is &lt;code&gt;a random computation&lt;/code&gt;. This is the desired result. The &lt;code&gt;Future&lt;/code&gt; takes time to complete and the rest of the code (below line 8) does not wait for it to complete but executes.
&lt;/li&gt;
&lt;li&gt;After a while, &lt;code&gt;recipes fetched&lt;/code&gt; and &lt;code&gt;after fetching recipes&lt;/code&gt; executes which were the callbacks for the &lt;code&gt;Future&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;



&lt;p&gt;So, &lt;code&gt;then&lt;/code&gt; fits here perfectly.&lt;/p&gt;

&lt;p&gt;Now let's see another use case.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After the &lt;code&gt;Future&lt;/code&gt; is completed (we've fetched the recipes), we want to display a message to the user.
&lt;/li&gt;
&lt;li&gt;We want to wait for the recipes to be fetched and not execute the lines below 8.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The easiest way would be to put all the code inside the &lt;code&gt;then&lt;/code&gt; block.  &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="n"&gt;fetching&lt;/span&gt; &lt;span class="n"&gt;recipes&lt;/span&gt;
&lt;span class="n"&gt;recipes&lt;/span&gt; &lt;span class="n"&gt;fetched&lt;/span&gt;
&lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="n"&gt;fetching&lt;/span&gt; &lt;span class="n"&gt;recipes&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt; &lt;span class="n"&gt;computation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We've just added everything under the &lt;code&gt;then&lt;/code&gt; block. Now, the &lt;code&gt;a random computation&lt;/code&gt; is executed after the recipes are fetched.&lt;/p&gt;

&lt;p&gt;There's a better way to implement this use case.&lt;br&gt;&lt;br&gt;
Since we want to wait for the recipes to be fetched and not execute the code below, we could use simpler syntax.&lt;br&gt;&lt;br&gt;
And that's what &lt;code&gt;async&lt;/code&gt; and &lt;code&gt;await&lt;/code&gt; are. An alternative syntax to implement asynchronous logic.&lt;/p&gt;
&lt;h2&gt;
  
  
  Using &lt;code&gt;async-await&lt;/code&gt; &lt;a id="using-async-await"&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Let's implement our second use case again. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="n"&gt;fetching&lt;/span&gt; &lt;span class="n"&gt;recipes&lt;/span&gt;
&lt;span class="n"&gt;recipes&lt;/span&gt; &lt;span class="n"&gt;fetched&lt;/span&gt;
&lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="n"&gt;fetching&lt;/span&gt; &lt;span class="n"&gt;recipes&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt; &lt;span class="n"&gt;computation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This time, we've not used any callbacks explicitly like the &lt;code&gt;then&lt;/code&gt; block. Instead, we've added &lt;code&gt;async&lt;/code&gt; in line 1 and &lt;code&gt;await&lt;/code&gt; in line 4.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;async&lt;/code&gt; keyword tells dart that this function might use asynchronous logic. So &lt;code&gt;void main&lt;/code&gt; has the &lt;code&gt;async&lt;/code&gt; keyword.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;await&lt;/code&gt; keyword tells dart that the following statement will return a &lt;code&gt;Future&lt;/code&gt;. The &lt;code&gt;Future&lt;/code&gt; should be completed and then the code below will be executed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's look at some more examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Samples &lt;a id="code-samples"&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;As seen above, we can have multiple implementations for the same logic. Let's look at some code samples and try to simplify them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sample 1 &lt;a id="sample-1"&gt;&lt;/a&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;delayed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;seconds:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'inside delayed'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'inside then'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'after delayed'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;then&lt;/code&gt; block is redundant here. Since we're &lt;code&gt;awaiting&lt;/code&gt; the &lt;code&gt;Future&lt;/code&gt;, the &lt;code&gt;then&lt;/code&gt; callback can be implemented like a normal code of block.&lt;/p&gt;

&lt;p&gt;Simplified:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;delayed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;seconds:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'inside delayed'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'inside then'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'after delayed'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Sample 2 &lt;a id="sample-2"&gt;&lt;/a&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;delayed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;seconds:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'inside delayed 1'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'inside then 1'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;delayed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;seconds:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'inside delayed 2'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'inside then 2'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'after delayed'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is a nesting of &lt;code&gt;then&lt;/code&gt; blocks here. We can use &lt;code&gt;async&lt;/code&gt;, &lt;code&gt;await&lt;/code&gt; syntax inside a &lt;code&gt;then&lt;/code&gt; block also.&lt;/p&gt;

&lt;p&gt;Simplified:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;delayed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;seconds:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'inside delayed 1'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'inside then 1'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;delayed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;seconds:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'inside delayed 2'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'inside then 2'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'after delayed'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I hope the examples helped in understanding the various syntaxes.&lt;br&gt;&lt;br&gt;
And that's it for asynchronous programming in dart using &lt;code&gt;Future&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion &lt;a id="conclusion"&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;We can use &lt;code&gt;then&lt;/code&gt; syntax or &lt;code&gt;async-await&lt;/code&gt; syntax or both to implement asynchronous logic.
&lt;/li&gt;
&lt;li&gt;Any syntax can be used to achieve our desired result. But we should also focus on code-readability.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;For further reading, you can refer to dart &lt;a href="https://dart.dev/codelabs/async-await" rel="noopener noreferrer"&gt;official docs&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Final Note &lt;a id="final-note"&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Thank you for reading this article. If you enjoyed it, consider sharing it with other people.&lt;br&gt;&lt;br&gt;
If you find any mistakes, please let me know.&lt;br&gt;&lt;br&gt;
Feel free to share your opinions below.&lt;/p&gt;

</description>
      <category>dart</category>
      <category>flutter</category>
      <category>tutorial</category>
      <category>learning</category>
    </item>
    <item>
      <title>8 Computer Networking Resources for All Levels</title>
      <dc:creator>Nikki Goel</dc:creator>
      <pubDate>Tue, 06 Jul 2021 09:16:48 +0000</pubDate>
      <link>https://dev.to/nicks101/8-computer-networking-resources-for-all-levels-766</link>
      <guid>https://dev.to/nicks101/8-computer-networking-resources-for-all-levels-766</guid>
      <description>&lt;p&gt;Where to study Computer Networking from?&lt;br&gt;&lt;br&gt;
Below is the list of Computer Networking resources that I use. These can be useful to everyone. No matter if you are a beginner, intermediate, or expert in the subject.&lt;br&gt;&lt;br&gt;
All of these are free except the last one.&lt;/p&gt;

&lt;p&gt;These are in no particular order.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. &lt;a href="https://www.youtube.com/c/HusseinNasser-software-engineering" rel="noopener noreferrer"&gt;Hussein Nasser - YouTube&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;This YouTube channel covers a wide range of topics. Some of them are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Databases &lt;/li&gt;
&lt;li&gt;Computer Networking &lt;/li&gt;
&lt;li&gt;General Software Engineering&lt;/li&gt;
&lt;li&gt;Career Advice&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are playlists such as beginners, intermediate and advanced. This gives an idea of where to start. There are other playlists as well for specific topics. The author also has many videos where he discusses the architecture and outages of tech companies.&lt;br&gt;&lt;br&gt;
There are practical examples along with the theory part. For example, a video explaining Nginx has a section of "making our own proxy using Nginx". This is my favorite thing about the channel.  &lt;/p&gt;

&lt;p&gt;The coding part is very helpful. I really like the energy of this guy and the content is understandable. This channel is what got me interested in Computer Networking in the first place.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. &lt;a href="https://www.youtube.com/user/elithecomputerguy" rel="noopener noreferrer"&gt;Eli the Computer Guy - YouTube&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;This channel has a variety of content, from web development to Computer Networking. Here we'll only focus on the Networking part.&lt;/p&gt;

&lt;p&gt;In many videos, alongside theory, the author also tells about the hardware component used with it. For example, when explaining a router, the author shows various physical router devices.&lt;br&gt;&lt;br&gt;
This helps us to fill a lot of gaps in our knowledge. Like identifying all the network-related physical devices.&lt;/p&gt;

&lt;p&gt;The videos might be a little old but are still valid as concepts never change.&lt;br&gt;&lt;br&gt;
This channel is for all levels as well. There is a playlist for Networking. It starts with basics and then progresses to advanced stuff.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. &lt;a href="https://packetlife.net/blog/" rel="noopener noreferrer"&gt;PacketLife - Blogs&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;This blog covers various Networking topics. We can browse by category if we want to learn about a particular niche.&lt;/p&gt;

&lt;p&gt;The writing style is such that the blogs are very easy to understand.&lt;br&gt;
The blogs usually start with an introduction and then proceed with an example. The examples are very detailed. There are step-by-step explanations and it feels like we are performing the example with him.  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://packetlife.net/blog/2010/jun/7/understanding-tcp-sequence-acknowledgment-numbers/" rel="noopener noreferrer"&gt;This&lt;/a&gt; is one of my favorite blogs in PacketLife. As a beginner, this helped me to get a hold of the concepts.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  4. &lt;a href="https://en.wikiversity.org/wiki/Network%2B" rel="noopener noreferrer"&gt;Network - WikiUniversity&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Wikipedia is one of the best resources out there. The Network WikiUniversity is a curated list of Computer Networking topics. It's structured like an online course.  &lt;/p&gt;

&lt;p&gt;Wikipedia gives everything there is to know about a topic.&lt;br&gt;&lt;br&gt;
There are definitions, examples, diagrams, advantages, disadvantages, timelines, and much more. This gives an overview of the subject and we can deep dive into any specific area that we like.&lt;br&gt;&lt;br&gt;
There are also references in the form of videos, RFCs, published technical papers, etc.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;One of my favorite thing about Wikipedia is, it gives unopinionated information. For a specific topic, it not only gives the advantages but also disadvantages as well. This helps in understanding when and when not to use that specific technology.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  5. &lt;a href="https://www.youtube.com/user/sunnylearning" rel="noopener noreferrer"&gt;Sunny Classroom - YouTube&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;This channel has amazing videos. Again there is a wide range of topics covered.&lt;br&gt;&lt;br&gt;
There are animated diagrams in the videos. This helps to visualize how data flows from one device to another. The roles of every entity like a router, ISP, switch, DNS, etc becomes crystal clear.&lt;br&gt;&lt;br&gt;
The videos are also clubbed together under various playlists so it's easy to navigate.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. &lt;a href="https://www.net.t-labs.tu-berlin.de/teaching/computer_networking/index.html" rel="noopener noreferrer"&gt;A Top-Down Approach Featuring the Internet - Book&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;This is one of the classic books out there for Computer Networking. The concepts are very well explained.&lt;br&gt;&lt;br&gt;
The fact that it's available as web pages on the internet for free is a bonus.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I have not read the whole book yet. I usually jump to the chapter that I want to read about, instead of the chronological order.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  7. &lt;a href="https://www.youtube.com/c/Certbros" rel="noopener noreferrer"&gt;CertBros - YouTube&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Another amazing YouTube channel.&lt;br&gt;&lt;br&gt;
This is structured more like a video course. This channel also covers various topics.&lt;br&gt;&lt;br&gt;
The videos have high production value. The sequence of videos in the playlist is ordered. That's a plus for beginners.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. &lt;a href="https://www.educative.io/courses/grokking-computer-networking" rel="noopener noreferrer"&gt;Grokking Computer Networking - Educative.io&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;This course is not free. Students with &lt;a href="https://www.educative.io/github-students" rel="noopener noreferrer"&gt;Student Github Pack&lt;/a&gt; can enroll in it for free.&lt;/p&gt;

&lt;p&gt;This is a text-based course as opposed to a video-based. That being said, this is one of the best courses I have ever studied. The amount of knowledge it provides is seamless. Everything is connected and well put together.  &lt;/p&gt;

&lt;p&gt;It takes time to finish it and that's a good thing. It means we are getting the information we hoped for. This makes the course worth it. This introduced me to various aspects of Computer Networking.&lt;br&gt;&lt;br&gt;
It also has quizzes, a final assessment, and a forum for doubts.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I am yet to complete the whole course. At the time of writing this blog, I've gone through the first half.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Honorable Mentions
&lt;/h2&gt;

&lt;p&gt;Below are the websites that often open up in the search engine results, whenever I search my Computer Networking doubts. They are mostly the lecture notes in the form of pdfs, slides, web pages, etc. These lecture notes are part of some university courses.&lt;br&gt;&lt;br&gt;
I often refer to them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.cs.miami.edu/home/burt/learning/Csc524.032/notes/" rel="noopener noreferrer"&gt;https://www.cs.miami.edu/home/burt/learning/Csc524.032/notes/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://web.cse.ohio-state.edu/%7Eathreya.14/cse3461-5461/" rel="noopener noreferrer"&gt;https://web.cse.ohio-state.edu/~athreya.14/cse3461-5461/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://www.ietf.org/" rel="noopener noreferrer"&gt;RFCs&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Last but not least, there are the RFCs (Request for Comments) documents. They are like technical documents but specific to the internet. Some of them are really detailed and it takes time to read them, but the information it provides is amazing. The community is also very active.  &lt;/p&gt;

&lt;p&gt;This concludes all the resources. 🎉🎉&lt;/p&gt;




&lt;h3&gt;
  
  
  Advice
&lt;/h3&gt;

&lt;p&gt;Computer Networking is a vast subject. One can feel overwhelmed during learning it. I definitely was overwhelmed when I first started it and I still do sometimes.&lt;br&gt;&lt;br&gt;
My advice would be to not dwell on the fact that there is too much to learn. We don't have to learn everything out there. Focusing only on one thing at a time helps. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I maintain a casual journal for tracking my weekly progress. If you feel too stressed out or overwhelmed, you can try this method. It may help you also.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Final Note
&lt;/h2&gt;

&lt;p&gt;Thank you for reading this article. If you enjoyed it, consider sharing it with other people.&lt;br&gt;&lt;br&gt;
If you find any mistakes, please let me know.&lt;br&gt;&lt;br&gt;
Feel free to share your opinions below.&lt;/p&gt;

</description>
      <category>computerscience</category>
      <category>networking</category>
      <category>productivity</category>
      <category>learning</category>
    </item>
    <item>
      <title>What is setState() in flutter and when to use it?</title>
      <dc:creator>Nikki Goel</dc:creator>
      <pubDate>Sun, 20 Jun 2021 12:05:14 +0000</pubDate>
      <link>https://dev.to/nicks101/when-to-use-setstate-in-flutter-380</link>
      <guid>https://dev.to/nicks101/when-to-use-setstate-in-flutter-380</guid>
      <description>&lt;p&gt;When working on frontend applications, a common use case is "Updating the screen's UI dynamically". &lt;code&gt;setState&lt;/code&gt; is one of the ways to accomplish this in flutter.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Tech Terms&lt;/li&gt;
&lt;li&gt;
What is a State Object in flutter

&lt;ul&gt;
&lt;li&gt;Fun Fact&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Example code&lt;/li&gt;

&lt;li&gt;When to use setState&lt;/li&gt;

&lt;li&gt;

Going one step ahead
&lt;/li&gt;

&lt;li&gt;Summary&lt;/li&gt;

&lt;li&gt;Final Note&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tech Terms &lt;a id="tech-terms"&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;These are some common terms used in flutter. The concepts apply to other frameworks also, although each framework has its own technical term for them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Widget: Any UI component on the screen is called a Widget in flutter. A Widget can have its own Widgets, like a tree structure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;StatefulWidget: A Widget that can change dynamically. Generally used when we want to modify something on the screen's UI.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is a State Object in flutter? &lt;a id="state"&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;setState&lt;/code&gt; is called inside a State class. Let's understand this in detail.&lt;br&gt;&lt;br&gt;
State is simply the information of a StatefulWidget. Every &lt;a href="https://api.flutter.dev/flutter/widgets/StatefulWidget-class.html" rel="noopener noreferrer"&gt;StatefulWidget&lt;/a&gt; has a State Object. This State Object keeps a track of the variables and functions that we define inside a StatefulWidget. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;State Object is actually managed by corresponding Element Object of the Widget, but for this blog, we will only focus on the Widget part. If you don't know what &lt;a href="https://api.flutter.dev/flutter/widgets/Element-class.html" rel="noopener noreferrer"&gt;Element&lt;/a&gt; Object is, I'll encourage you to read about it. It's not required to know for this blog though.&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyWidget&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatefulWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// immutable Widget&lt;/span&gt;
  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;_MyWidgetState&lt;/span&gt; &lt;span class="n"&gt;createState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_MyWidgetState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="c1"&gt;// creating State Object of MyWidget&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;_MyWidgetState&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MyWidget&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// State Object&lt;/span&gt;
  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since StatefulWidget itself is immutable (cannot be modified), we use &lt;a href="https://api.flutter.dev/flutter/widgets/State-class.html" rel="noopener noreferrer"&gt;State Object&lt;/a&gt; to modify the UI.&lt;br&gt;&lt;br&gt;
We tell this State Object to update our screen's UI using a function called &lt;code&gt;setState()&lt;/code&gt;.&lt;/p&gt;
&lt;h4&gt;
  
  
  Function Definition
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;VoidCallback&lt;/span&gt; &lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This &lt;code&gt;setState()&lt;/code&gt; takes a function as it's parameter.&lt;br&gt;&lt;br&gt;
&lt;code&gt;VoidCallback&lt;/code&gt; is just a fancy way of saying: &lt;code&gt;void Function()&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;typedef&lt;/span&gt; &lt;span class="n"&gt;VoidCallback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="kt"&gt;Function&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;We'll create a simple counter app (I know it's very common but bear with me). &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This will have a variable &lt;code&gt;counter&lt;/code&gt; initialized with &lt;code&gt;0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;We will display this &lt;code&gt;counter&lt;/code&gt; on the screen inside the &lt;code&gt;Text&lt;/code&gt; Widget.&lt;/li&gt;
&lt;li&gt;Next, we'll have a button that increases this &lt;code&gt;counter&lt;/code&gt;'s value by &lt;code&gt;1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The UI should be updated with the new value of &lt;code&gt;counter&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Let's see the steps written above one by one.
&lt;/h4&gt;

&lt;h6&gt;
  
  
  When the Widget is created, the value of the counter is 0
&lt;/h6&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h6&gt;
  
  
  Displaying value of counter on screen
&lt;/h6&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; 
       &lt;span class="p"&gt;...&lt;/span&gt;
       &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="nl"&gt;value:&lt;/span&gt; &lt;span class="n"&gt;$counter&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h6&gt;
  
  
  When we click on a button, we increment the value of the counter
&lt;/h6&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="nl"&gt;onTap:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="c1"&gt;// passing an anonymous function to setState&lt;/span&gt;
  &lt;span class="c1"&gt;// that increments counter's value by 1&lt;/span&gt;
  &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h6&gt;
  
  
  Update the UI
&lt;/h6&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="nl"&gt;onTap:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="c1"&gt;// passing an anonymous function to setState&lt;/span&gt;
  &lt;span class="c1"&gt;// that increments counter's value by 1&lt;/span&gt;
  &lt;span class="c1"&gt;// and update the UI&lt;/span&gt;
  &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  #Fun Fact : &lt;a id="fun-fact-1"&gt;&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;We can update our variables first and then call the &lt;code&gt;setState()&lt;/code&gt; function, since &lt;code&gt;setState&lt;/code&gt; just informs the underlying framework that &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"update this Widget's UI in next frame" (&lt;code&gt;marks it dirty&lt;/code&gt;).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The underlying framework will use the last value that is defined before calling the &lt;code&gt;setState&lt;/code&gt; function. &lt;/p&gt;

&lt;h5&gt;
  
  
  This is the same as above
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="nl"&gt;onTap:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Example Code &lt;a id="example-code"&gt;&lt;/a&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter/material.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyWidget&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatefulWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;   &lt;span class="c1"&gt;// widget class&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;MyWidget&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;key:&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;_MyWidgetState&lt;/span&gt; &lt;span class="n"&gt;createState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_MyWidgetState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;_MyWidgetState&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MyWidget&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  &lt;span class="c1"&gt;// state class&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// initializing counter&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;mainAxisAlignment:&lt;/span&gt; &lt;span class="n"&gt;MainAxisAlignment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;center&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;crossAxisAlignment:&lt;/span&gt; &lt;span class="n"&gt;CrossAxisAlignment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stretch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;

          &lt;span class="c1"&gt;// displaing the counter&lt;/span&gt;
          &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;'counter value: &lt;/span&gt;&lt;span class="si"&gt;$counter&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nl"&gt;textAlign:&lt;/span&gt; &lt;span class="n"&gt;TextAlign&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;center&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="n"&gt;TextButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;onPressed:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

              &lt;span class="c1"&gt;//incrementing counter&lt;/span&gt;
              &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
              &lt;span class="p"&gt;});&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Tap here to increment counter'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  When to use setState() ? &lt;a id="setsate-use"&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;When we want to change the UI of the screen.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We don't need to call &lt;code&gt;setState&lt;/code&gt; every time we change a variable. We call &lt;code&gt;setState&lt;/code&gt; only when we want the change in a variable to reflect on the UI of the screen.&lt;/p&gt;

&lt;p&gt;For instance, say you have a form containing a text field and a button to submit it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter/material.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyForm&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatefulWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;MyForm&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;key:&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;_MyFormState&lt;/span&gt; &lt;span class="n"&gt;createState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_MyFormState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;_MyFormState&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MyForm&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;

        &lt;span class="c1"&gt;// text field&lt;/span&gt;
        &lt;span class="n"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;TextFormField&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;

        &lt;span class="c1"&gt;// submit button&lt;/span&gt;
        &lt;span class="n"&gt;OutlinedButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nl"&gt;onPressed:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
          &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Submit'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;User types in the text field and clicks on submit button. Then we display that text field's text below the submit button.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter/material.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyForm&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatefulWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;MyForm&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;key:&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;_MyFormState&lt;/span&gt; &lt;span class="n"&gt;createState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_MyFormState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;_MyFormState&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MyForm&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// we'll use this to save the text user types&lt;/span&gt;
  &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;userText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// this will keep track of submit button's tapped action/event&lt;/span&gt;
  &lt;span class="c1"&gt;// and display the userText below submit button&lt;/span&gt;
  &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;hasSubmitted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="n"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;TextFormField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;

            &lt;span class="c1"&gt;// triggered when we save the form&lt;/span&gt;
            &lt;span class="nl"&gt;onSaved:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="c1"&gt;// store the text-field's value into&lt;/span&gt;
              &lt;span class="c1"&gt;// the userText variable&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;OutlinedButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;

          &lt;span class="c1"&gt;// this is triggered whenever we click on button  &lt;/span&gt;
          &lt;span class="nl"&gt;onPressed:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// validate and save the form&lt;/span&gt;
            &lt;span class="c1"&gt;// display the text below the button&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Submit'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;

        &lt;span class="c1"&gt;// this will display the userText only&lt;/span&gt;
        &lt;span class="c1"&gt;// if user has clicked on submit button&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hasSubmitted&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userText&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User types in the text-field&lt;/li&gt;
&lt;li&gt;User clicks submit button&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;onPressed&lt;/code&gt; function of submit button is triggered&lt;/li&gt;
&lt;li&gt;Inside &lt;code&gt;onPressed&lt;/code&gt; function:

&lt;ol&gt;
&lt;li&gt;Validate and save the form&lt;/li&gt;
&lt;li&gt;This will trigger the &lt;code&gt;onSaved&lt;/code&gt; function in the &lt;code&gt;TextFormField&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Inside &lt;code&gt;onSaved&lt;/code&gt; function:

&lt;ol&gt;
&lt;li&gt;Store the text field's value in the &lt;code&gt;userText&lt;/code&gt; variable&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;Update &lt;code&gt;hasSubmitted&lt;/code&gt; variable with &lt;code&gt;true&lt;/code&gt;
&lt;/li&gt;

&lt;/ol&gt;

&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;Implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter/material.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyForm&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatefulWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;MyForm&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;key:&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;_MyFormState&lt;/span&gt; &lt;span class="n"&gt;createState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_MyFormState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;_MyFormState&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MyForm&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;userText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;hasSubmitted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// for getting access to form&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;_formKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GlobalKey&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;FormState&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="n"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="c1"&gt;// attaching key to form&lt;/span&gt;
          &lt;span class="nl"&gt;key:&lt;/span&gt; &lt;span class="n"&gt;_formKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;TextFormField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;onSaved:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="c1"&gt;/// updating userText variable&lt;/span&gt;
              &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;userText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;OutlinedButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nl"&gt;onPressed:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// validating form&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;_formKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentState&lt;/span&gt;&lt;span class="o"&gt;!.&lt;/span&gt;&lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="c1"&gt;// saving form&lt;/span&gt;
            &lt;span class="n"&gt;_formKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentState&lt;/span&gt;&lt;span class="o"&gt;!.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="c1"&gt;// updating hasSubmitted&lt;/span&gt;
            &lt;span class="n"&gt;hasSubmitted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Submit'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hasSubmitted&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userText&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's one small step left.&lt;br&gt;
When you run this program, you'll notice that nothing happens when we click on submit button.&lt;br&gt;&lt;br&gt;
Here &lt;code&gt;setState&lt;/code&gt; comes to the rescue!&lt;/p&gt;

&lt;p&gt;Now the question is where should we call it?&lt;br&gt;&lt;br&gt;
There are two places in the program where we are updating variables.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;inside &lt;code&gt;onSaved&lt;/code&gt; function&lt;/li&gt;
&lt;li&gt;insided &lt;code&gt;onPressed&lt;/code&gt; function&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So either one of these or both places should be the answer.&lt;/p&gt;

&lt;p&gt;Let's ask one question to ourselves.&lt;br&gt;&lt;br&gt;
"On which variable update, do I want to update the UI of the screen?"&lt;br&gt;&lt;br&gt;
Is it &lt;code&gt;userText&lt;/code&gt; inside &lt;code&gt;onSaved&lt;/code&gt; function&lt;br&gt;&lt;br&gt;
or&lt;br&gt;&lt;br&gt;
&lt;code&gt;hasSubmitted&lt;/code&gt; inside &lt;code&gt;onPressed&lt;/code&gt; function?  &lt;/p&gt;

&lt;p&gt;You got it right!&lt;br&gt;&lt;br&gt;
It's inside the &lt;code&gt;onPressed&lt;/code&gt; function after the &lt;code&gt;hasSubmitted&lt;/code&gt; variable has been updated.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="nl"&gt;onPressed:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// validating form&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;_formKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentState&lt;/span&gt;&lt;span class="o"&gt;!.&lt;/span&gt;&lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// saving form&lt;/span&gt;
  &lt;span class="n"&gt;_formKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentState&lt;/span&gt;&lt;span class="o"&gt;!.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// updating hasSubmitted&lt;/span&gt;
  &lt;span class="n"&gt;hasSubmitted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, this is same as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="nl"&gt;onPressed:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// validating form&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;_formKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentState&lt;/span&gt;&lt;span class="o"&gt;!.&lt;/span&gt;&lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// saving form&lt;/span&gt;
  &lt;span class="n"&gt;_formKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentState&lt;/span&gt;&lt;span class="o"&gt;!.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// updating hasSubmitted&lt;/span&gt;
    &lt;span class="n"&gt;hasSubmitted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why use &lt;code&gt;setState&lt;/code&gt; here?&lt;br&gt;&lt;br&gt;
In our logic, we used &lt;code&gt;hasSubmitted&lt;/code&gt; variable as a condition to show the &lt;code&gt;userText&lt;/code&gt;. So only after updating &lt;code&gt;hasSubmitted&lt;/code&gt; value, does the UI show our desired result.&lt;/p&gt;
&lt;h2&gt;
  
  
  Going one step ahead &lt;a id="more"&gt;&lt;/a&gt;:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;What happens when you use the &lt;code&gt;setState&lt;/code&gt; inside the &lt;code&gt;onSaved&lt;/code&gt; function only?
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="nl"&gt;onSaved:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;/// updating userText variable&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;userText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="n"&gt;OutlinedButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nl"&gt;onPressed:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;// validating form&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;_formKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentState&lt;/span&gt;&lt;span class="o"&gt;!.&lt;/span&gt;&lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// saving form&lt;/span&gt;
    &lt;span class="n"&gt;_formKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentState&lt;/span&gt;&lt;span class="o"&gt;!.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// updating hasSubmitted&lt;/span&gt;
    &lt;span class="n"&gt;hasSubmitted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;It works here also. Surprise!!&lt;br&gt;&lt;br&gt;
But why? This goes against everything we've read so far in this blog.  &lt;/p&gt;

&lt;p&gt;So here's what happens.&lt;br&gt;&lt;br&gt;
When we call &lt;code&gt;setState&lt;/code&gt;, the Widget inside we called it is marked as &lt;code&gt;dirty&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
Now whenever the framework actually rebuilds the UI of the screen, it will take into account all the latest values of the respective variables and paint the pixels on the screen.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This happens 60 times per second usually, which is the frame per second (&lt;a href="https://flutter.dev/docs/perf/rendering/ui-performance#:~:text=Flutter%20aims%20to%20provide%2060,UI%20doesn't%20render%20smoothly" rel="noopener noreferrer"&gt;fps&lt;/a&gt;) rate of flutter. That means approximately every 16ms (1000/60 ms).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If there is any other change until the next frame renders, those changes will also be reflected on the screen's UI.&lt;/p&gt;

&lt;p&gt;The change in &lt;code&gt;hasSubmitted&lt;/code&gt; variable falls under such case.&lt;/p&gt;

&lt;p&gt;How do we verify it?&lt;br&gt;&lt;br&gt;
Let's add print statements and see exactly when does the UI actually rebuild.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter/material.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyForm&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatefulWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;MyForm&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;key:&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;_MyFormState&lt;/span&gt; &lt;span class="n"&gt;createState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_MyFormState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;_MyFormState&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MyForm&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;userText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;hasSubmitted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// for getting access to form&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;_formKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GlobalKey&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;FormState&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Widget build called'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="n"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="c1"&gt;// attaching key to form&lt;/span&gt;
          &lt;span class="nl"&gt;key:&lt;/span&gt; &lt;span class="n"&gt;_formKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;TextFormField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;onSaved:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'inside save'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

              &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;userText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

              &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'hasSubmitted value before setState: &lt;/span&gt;&lt;span class="si"&gt;$hasSubmitted&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

              &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt;

              &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'hasSubmitted value after setState: &lt;/span&gt;&lt;span class="si"&gt;$hasSubmitted&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;OutlinedButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nl"&gt;onPressed:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'button clicked: -&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;// validating form&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;_formKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentState&lt;/span&gt;&lt;span class="o"&gt;!.&lt;/span&gt;&lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'before calling save'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;// saving form&lt;/span&gt;
            &lt;span class="n"&gt;_formKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentState&lt;/span&gt;&lt;span class="o"&gt;!.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'after calling save'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'hasSubmitted value after calling save: &lt;/span&gt;&lt;span class="si"&gt;$hasSubmitted&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;// updating hasSubmitted&lt;/span&gt;
            &lt;span class="n"&gt;hasSubmitted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="s"&gt;'hasSubmitted value after updating hasSubmitted: &lt;/span&gt;&lt;span class="si"&gt;$hasSubmitted&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Submit'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hasSubmitted&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userText&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With these print statements, we can see the order in which the flutter framework updates the UI.&lt;br&gt;&lt;br&gt;
Let's write something in the text field and click on submit button.&lt;/p&gt;

&lt;p&gt;Inside console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt; &lt;span class="n"&gt;called&lt;/span&gt;
&lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="nl"&gt;clicked:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="n"&gt;calling&lt;/span&gt; &lt;span class="n"&gt;save&lt;/span&gt;
&lt;span class="n"&gt;inside&lt;/span&gt; &lt;span class="n"&gt;save&lt;/span&gt;
&lt;span class="n"&gt;hasSubmitted&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="nl"&gt;setState:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="n"&gt;hasSubmitted&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="nl"&gt;setState:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="n"&gt;calling&lt;/span&gt; &lt;span class="n"&gt;save&lt;/span&gt;
&lt;span class="n"&gt;hasSubmitted&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="n"&gt;calling&lt;/span&gt; &lt;span class="nl"&gt;save:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="n"&gt;hasSubmitted&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="n"&gt;updating&lt;/span&gt; &lt;span class="nl"&gt;hasSubmitted:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt; &lt;span class="n"&gt;called&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clearly, the Widget is built after the &lt;code&gt;hasSubmitted&lt;/code&gt; is set to &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So the major question is: "Why can't we use &lt;code&gt;setState&lt;/code&gt; inside &lt;code&gt;onSaved&lt;/code&gt; function instead of inside &lt;code&gt;onPressed&lt;/code&gt; function, it seems to work fine."&lt;/p&gt;

&lt;p&gt;Because this method doesn't work for all the use cases. And it is also logically wrong.&lt;br&gt;
When you'll come back to refactor the code (like for adding a new feature), things might not work as expected. Debugging the code will also be difficult since the problem is in the old code.&lt;br&gt;&lt;br&gt;
Let's see an example of such a use case. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Okay, we're almost done. This is the most important part. We've been building up to this point since the starting of this blog.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's go back to the steps of this example and add one more thing to it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After saving the form, say we want to make an API call to send the data that the user typed to a server. For simplicity, let's say we're going to do some computation with the &lt;code&gt;userText&lt;/code&gt; data which will take a minimum of 20ms (this can be any duration of your choice).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a practical example. Usually, we do communicate with our application's backend server.&lt;/p&gt;

&lt;p&gt;Does our desired result still happen?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="nl"&gt;onPressed:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'button clicked: -&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// validating form&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;_formKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentState&lt;/span&gt;&lt;span class="o"&gt;!.&lt;/span&gt;&lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'before calling save'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// saving form&lt;/span&gt;
  &lt;span class="n"&gt;_formKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentState&lt;/span&gt;&lt;span class="o"&gt;!.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'after calling save'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'hasSubmitted value after calling save: &lt;/span&gt;&lt;span class="si"&gt;$hasSubmitted&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;/// some computation that takes 20ms&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;delayed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;milliseconds:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt;

  &lt;span class="c1"&gt;// updating hasSubmitted after 20ms&lt;/span&gt;
  &lt;span class="n"&gt;hasSubmitted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="s"&gt;'hasSubmitted value after updating hasSubmitted: &lt;/span&gt;&lt;span class="si"&gt;$hasSubmitted&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See inside &lt;code&gt;onPressed&lt;/code&gt; function. We're &lt;code&gt;awating&lt;/code&gt; a &lt;code&gt;Future&lt;/code&gt; and then updating the &lt;code&gt;hasSubmitted&lt;/code&gt; value.   &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you don't know what await, async and Future means, then just think that we're basically saying to program, "Hey flutter framework, we're gonna do some task that'll probably take some time. Please do it in the next iteration."&lt;br&gt;
I'll encourage you to read about &lt;a href="https://dart.dev/codelabs/async-await" rel="noopener noreferrer"&gt;asynchronous programming&lt;/a&gt;. This concept is not exclusive to dart.  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h5&gt;
  
  
  #Note: We can also use a &lt;a href="https://api.dart.dev/stable/2.12.0/dart-async/Timer-class.html" rel="noopener noreferrer"&gt;Timer&lt;/a&gt; to get the same effect, but here we'll use &lt;a href="https://api.dart.dev/stable/2.13.3/dart-async/Future-class.html" rel="noopener noreferrer"&gt;Future&lt;/a&gt;.
&lt;/h5&gt;

&lt;p&gt;Inside console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt; &lt;span class="n"&gt;called&lt;/span&gt;
&lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="nl"&gt;clicked:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="n"&gt;calling&lt;/span&gt; &lt;span class="n"&gt;save&lt;/span&gt;
&lt;span class="n"&gt;inside&lt;/span&gt; &lt;span class="n"&gt;save&lt;/span&gt;
&lt;span class="n"&gt;hasSubmitted&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="nl"&gt;setState:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="n"&gt;hasSubmitted&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="nl"&gt;setState:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="n"&gt;calling&lt;/span&gt; &lt;span class="n"&gt;save&lt;/span&gt;
&lt;span class="n"&gt;hasSubmitted&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="n"&gt;calling&lt;/span&gt; &lt;span class="nl"&gt;save:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt; &lt;span class="n"&gt;called&lt;/span&gt;
&lt;span class="n"&gt;hasSubmitted&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="n"&gt;updating&lt;/span&gt; &lt;span class="nl"&gt;hasSubmitted:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we don't see the UI updates on the screen. And according to our print statements order, &lt;code&gt;hasSubmitted&lt;/code&gt; variable is updated after the Widget has been rebuilt.&lt;/p&gt;

&lt;p&gt;Reason?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Warning: This includes some advanced topics. I'll try to explain it as simply as possible.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There is a &lt;a href="https://en.wikipedia.org/wiki/Queue_%28abstract_data_type%29" rel="noopener noreferrer"&gt;queue&lt;/a&gt; of microtasks. One by one all the tasks are performed by dart. When we use &lt;code&gt;await&lt;/code&gt;, we tell dart to first complete the current task (waiting for 20 ms), then move on to the next one in the queue.&lt;br&gt;&lt;br&gt;
So although some tasks (like rendering of the screen and waiting for 20 ms) are being performed concurrently, the tasks below the &lt;code&gt;await&lt;/code&gt; keyword (updating &lt;code&gt;hasSubmitted&lt;/code&gt; variable) will not be performed till the current task is completed.&lt;/p&gt;

&lt;p&gt;So, when the framework actually rendered the &lt;code&gt;dirty&lt;/code&gt; Widget(MyForm), &lt;code&gt;hasSubmitted&lt;/code&gt; variable's value was not updated. Hence we don't see our typed text below the submit button.&lt;/p&gt;

&lt;p&gt;Something to search about:&lt;br&gt;&lt;br&gt;
There is also an &lt;code&gt;event queue&lt;/code&gt;. When we don't wait for the Future to complete but want to continue on to the next microtask, the task in Future is added to &lt;code&gt;event queue&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Want to experiment more?&lt;br&gt;&lt;br&gt;
Try changing the duration to 0 seconds.&lt;/p&gt;

&lt;p&gt;The UI still doesn't update as desired.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you wanna dig deep into why after encountering the &lt;code&gt;await&lt;/code&gt; keyword, does the code below it doesn't run synchronously even if the duration is 0 seconds, then read about the &lt;a href="https://dart.cn/articles/archive/event-loop" rel="noopener noreferrer"&gt;event loop&lt;/a&gt; in dart. There are other resources also that you can easily find on the internet. This concept is not exclusive to dart.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With this new use case (using a Future), our desired output is not achieved. Below is the short summary.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;   &lt;span class="c1"&gt;/// Approach 1: this is good (recommended)&lt;/span&gt;
   &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;((){&lt;/span&gt;
     &lt;span class="n"&gt;hasSubmitted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;});&lt;/span&gt;

   &lt;span class="p"&gt;...&lt;/span&gt;

   &lt;span class="c1"&gt;/// Approach 2: this is also good&lt;/span&gt;
   &lt;span class="n"&gt;hasSubmitted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;((){});&lt;/span&gt;

   &lt;span class="p"&gt;...&lt;/span&gt;

   &lt;span class="c1"&gt;/// Approach 3: this is not good&lt;/span&gt;
   &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;((){});&lt;/span&gt;
   &lt;span class="n"&gt;hasSubmitted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;What happens when we use &lt;code&gt;setState&lt;/code&gt; inside both the functions?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This case is dangerous.&lt;br&gt;&lt;br&gt;
Since our desired result is achieved, we overlook the one extra call to &lt;code&gt;setState&lt;/code&gt; inside the &lt;code&gt;onSaved&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;I hope now you got an idea of when and when not to use &lt;code&gt;setState&lt;/code&gt;.&lt;/p&gt;




&lt;p&gt;Since this was a very simple example with only two variables to think of, it's easy to implement our logic into code.&lt;/p&gt;

&lt;p&gt;When the program becomes bigger and complicated, keeping track of updating the variables and UI becomes cumbersome.&lt;br&gt;&lt;br&gt;
Then we use a mix of StatefulWidget's &lt;code&gt;setState&lt;/code&gt; and/or some other &lt;a href="https://flutter.dev/docs/development/data-and-backend/state-mgmt/options" rel="noopener noreferrer"&gt;state management&lt;/a&gt; solution.&lt;/p&gt;

&lt;p&gt;I'll encourage you to read flutter official &lt;a href="https://flutter.dev/docs/development/ui/interactive" rel="noopener noreferrer"&gt;docs&lt;/a&gt; and build apps to get a grip on this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary &lt;a id="summary"&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;setState&lt;/code&gt; is a way to dynamically change the UI.&lt;/li&gt;
&lt;li&gt;We call it inside the State Object class of the StatefulWidget.&lt;/li&gt;
&lt;li&gt;Calling &lt;code&gt;setState&lt;/code&gt; marks the corresponding Widget &lt;code&gt;dirty&lt;/code&gt;. When flutter builds the next frame (approx. every 16ms), it renders the Widget according to the latest values of the State Object.&lt;/li&gt;
&lt;li&gt;Where we call &lt;code&gt;setState&lt;/code&gt; matters a lot.&lt;/li&gt;
&lt;li&gt;There are other state management solutions also.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final Note &lt;a id="final-note"&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Thank you for reading this article. If you enjoyed it, consider sharing it with other people.&lt;br&gt;&lt;br&gt;
If you find any mistakes, please let me know.&lt;br&gt;&lt;br&gt;
Feel free to share your opinions below.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>mobile</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
