<?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>How “Design Patterns Explained” Changed the Way I Design Software</title>
      <dc:creator>Nikki Goel</dc:creator>
      <pubDate>Tue, 02 Jun 2026 18:45:22 +0000</pubDate>
      <link>https://dev.to/nicks101/how-design-patterns-explained-changed-the-way-i-design-software-15g3</link>
      <guid>https://dev.to/nicks101/how-design-patterns-explained-changed-the-way-i-design-software-15g3</guid>
      <description>&lt;p&gt;I read &lt;a href="https://www.goodreads.com/book/show/85021.Design_Patterns_Explained" rel="noopener noreferrer"&gt;Design Patterns Explained 2nd Edition&lt;/a&gt; a few months ago. I thought I'd finally write about it and some of the lessons I took away from it.&lt;br&gt;&lt;br&gt;
I was reading the final chapters while starting &lt;em&gt;Offline Dashcam&lt;/em&gt;, a project at &lt;a href="https://www.linkedin.com/company/wheelseye" rel="noopener noreferrer"&gt;Wheelseye&lt;/a&gt;, a logistics company. Looking back, it was the perfect project to apply many of the ideas from the book.&lt;br&gt;&lt;br&gt;
This article is about how the principles in the book helped me design and code a complex feature.&lt;/p&gt;
&lt;h2&gt;
  
  
  A Shift in Thinking
&lt;/h2&gt;

&lt;p&gt;There are books that give information or are used as references. But sometimes you read a book that changes the way you think.&lt;/p&gt;

&lt;p&gt;Design Patterns Explained is one of those books for me. The book is for anyone who is looking to understand design patterns, not just catalog them, but actually understand why they exist, what problems they solve, how to recognise, implement, and refactor them.&lt;/p&gt;

&lt;p&gt;It explained encapsulation through tons of examples, along with concepts like abstraction, polymorphism, and inheritance. More importantly, it showed how these ideas influence real design decisions: which classes should be abstracted and how classes should relate to and aggregate one another.&lt;/p&gt;

&lt;p&gt;As engineers, we know features evolve. A “simple” requirement today can grow into something much bigger tomorrow.&lt;/p&gt;

&lt;p&gt;I always tried to be ready for that. But I sometimes focused on the wrong kind of change. Things worked, they shipped — but updating them wasn’t always smooth. I knew I could improve how I approached design, but I couldn’t clearly explain what was missing.&lt;/p&gt;

&lt;p&gt;I didn’t read &lt;strong&gt;Design Patterns Explained&lt;/strong&gt; to solve this. I picked it up just to understand design patterns better.&lt;br&gt;&lt;br&gt;
But while reading, I started noticing the missing pieces in my own decisions.&lt;br&gt;&lt;br&gt;
And those realisations changed how I design software today.&lt;/p&gt;

&lt;p&gt;This book didn’t teach me patterns. It changed how I think. And once that happened, patterns showed up naturally in my code.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Design Is Mostly About Change&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;One idea hit me early in the book:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Build for today. But keep the door open for tomorrow.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;My usual flow was:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Understand the feature&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Code it&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adjust later&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It wasn’t wrong. It just wasn’t always ready for the &lt;em&gt;right&lt;/em&gt; changes.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;&lt;em&gt;Offline Dashcam&lt;/em&gt;&lt;/strong&gt; is a device with a built-in wireless hotspot and an SD card slot. It is attached to a vehicle and records video to the SD card. We can connect to its Wi-Fi to view, download, and delete those recordings. I was working on adding support for this feature in our mobile application (built using Flutter 💙).&lt;/p&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%2Fzulv50kygj5yt1zl88qt.png" 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%2Fzulv50kygj5yt1zl88qt.png" alt="Offline Dashcam device with phone connected" width="266" height="190"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each vendor has different firmware with different chipsets. This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Different API endpoints&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Different request bodies &amp;amp; responses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Different capabilities&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We need to keep our codebase open to adding new chipsets, while maintaining the capabilities of each one without disrupting user experience.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Principles Before Patterns&lt;/strong&gt;
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Encapsulate what varies.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Before reading the book, I would often think in terms of features. The book pushed me to think in terms of change. Instead of asking "What does this feature do?", I started asking "What part of this feature is likely to change independently?"&lt;/p&gt;

&lt;p&gt;I created a list of things that were likely to vary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The chipset initialisation process is different for each chipset.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The API endpoints and response protocols are different.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Capabilities of each chipset are different. (E.g. audio support)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What stayed the same was more interesting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start Recording&lt;/li&gt;
&lt;li&gt;Stop Recording&lt;/li&gt;
&lt;li&gt;Delete File&lt;/li&gt;
&lt;li&gt;Get Device Info&lt;/li&gt;
&lt;li&gt;Get Recordings&lt;/li&gt;
&lt;li&gt;Take Snapshot&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No matter which chipset the user connected to, the app still needed to perform the same operations.&lt;/p&gt;

&lt;p&gt;That led me to a simple question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What if the rest of the application only knew about these operations and never about the chipset itself?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I introduced a common repository contract:&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;OfflineDashcamRepository&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;startRecording&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;stopRecording&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;DashcamMedia&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getDeviceData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;DashcamDeviceInfo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getDeviceAttributes&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;Each chipset implemented the same contract in its own way, allowing the rest of the application to remain unaware of vendor-specific details.&lt;/p&gt;

&lt;p&gt;This confirmed that each chipset should have its own repository and API layer. The rest of the layers should not be aware of these differences. The initialisation process also varied by chipset. To keep that complexity from spreading through the application, I introduced a factory that selects the correct repository implementation during onboarding. From that point onward, the rest of the application works through a common abstraction.&lt;br&gt;
I explored different approaches, applied the "encapsulate what varies" principle to each of them, and chose the design that best matched the kinds of change I expected.&lt;/p&gt;

&lt;p&gt;Before, chipset differences leaked into business logic:&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chipset&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;Chipset&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;gk7201&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;gkApi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDeviceAttributes&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="k"&gt;else&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;chipset&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;Chipset&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hisilicon&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;hisiApi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDeviceAttributes&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;Every new chipset meant more conditionals scattered throughout the codebase.&lt;/p&gt;

&lt;p&gt;Instead, the chipset is detected once during onboarding:&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;chipset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;chipsetDetector&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;detectChipsetType&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;repository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;dashcamRepositoryFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chipset&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From that point onward, the rest of the application talks only to the repository abstraction:&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;deviceInfo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDeviceAttributes&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The use cases, Blocs, and UI never need to know which chipset is connected.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How This Changed My Architecture Decisions&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Chipset differences do not spread through the codebase.&lt;br&gt;&lt;br&gt;
They live in one place.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;               OfflineDashcamRepository
                           ▲
                           │
        ┌──────────────────┴──────────────────┐
        │                                     │
Gk7201DashcamRepositoryImpl   HisiliconDashcamRepositoryImpl
        │                                     │
        ▼                                     ▼
 Gk7201 API Service               Hisilicon API Service


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
        OfflineDashcamRepository

                │
                ▼

             Use Case
                │
                ▼

               BLoC
                │
                ▼

                UI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The chipset-specific logic exists only in the API and repository layers.&lt;/p&gt;

&lt;p&gt;Everything above the repository layer depends on abstractions. Adding a new chipset means creating a new implementation, not rewriting the UI, BLoCs, or use cases.&lt;/p&gt;

&lt;p&gt;At runtime, the correct implementation is selected.&lt;br&gt;&lt;br&gt;
The rest of the system doesn’t need to know which chipset it is talking to.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;A Practical Insight I Took Away&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;When I stopped thinking &lt;em&gt;“which pattern should I use?”&lt;/em&gt;&lt;br&gt;&lt;br&gt;
and instead started asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What here is stable, and what is likely to change?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this case, chipsets changed. The operations the app needed to perform did not.&lt;br&gt;
Now I look for variability by asking questions. I interrogate new code: Does this depend on specific hardware? Will another vendor break this? Can the UI team change a colour without me refactoring the API layer? If the answer is yes, that piece gets its own box. Its own boundary. Its own file where it can change without asking permission.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Keeping Things Cohesive&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Earlier, I sometimes built giant “god” BLoCs or Services that handled everything.&lt;br&gt;&lt;br&gt;
But now, I have use cases, which delegate to services, factories, repositories, etc., as needed.&lt;/p&gt;

&lt;p&gt;Now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;UI layer handles UI stuff&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Storage handles storage stuff&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hardware/API code stays near hardware/API code&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No giant boss-component running the whole show.&lt;br&gt;&lt;br&gt;
If a new engineer joins later, they won’t have to decode one huge file to make a small change.&lt;/p&gt;

&lt;p&gt;High cohesion → less stress.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;A Real Change in Everyday Workflow&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Earlier, if a new requirement came in — for example, &lt;em&gt;“Also support taking snapshots while recording”&lt;/em&gt; — I would hesitate a bit.&lt;/p&gt;

&lt;p&gt;Where should that logic go? Will it break recording flow? Will I end up refactoring too much?&lt;/p&gt;

&lt;p&gt;Now, the path is clear:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A new feature → a new use case&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hardware behaviour → a new chipset implementation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API change → stays near the API service&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;UI behaviour → stays in its own layer&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Refactoring and testing became more predictable because each piece has its own space.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;When code has the right boundaries, future change stops feeling risky.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What Changed in Me (and What’s Next)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I didn’t expect this book to influence my day-to-day work.&lt;br&gt;&lt;br&gt;
But I caught myself designing with more clarity from the very next feature.&lt;/p&gt;

&lt;p&gt;Now, I:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;notice variability early&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;keep change local&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;choose simplicity by default&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;and think about the developer who joins after me&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’m still learning to balance all this, but my software is starting to feel more ready for whatever comes next.&lt;br&gt;&lt;br&gt;
If you’ve ever felt your code works but it doesn’t feel quite ready for the future, this book might help you spot the same gaps I did.&lt;/p&gt;

&lt;p&gt;I picked up the book hoping to learn design patterns. I finished it thinking differently about change. The patterns were useful, but the mindset shift was what stayed with me.&lt;/p&gt;

</description>
      <category>designpatterns</category>
      <category>books</category>
      <category>architecture</category>
      <category>devlog</category>
    </item>
    <item>
      <title>I Don’t Know Machine Learning as Well as I Thought I Did</title>
      <dc:creator>Nikki Goel</dc:creator>
      <pubDate>Sun, 24 May 2026 16:14:04 +0000</pubDate>
      <link>https://dev.to/nicks101/i-dont-know-machine-learning-as-well-as-i-thought-i-did-kan</link>
      <guid>https://dev.to/nicks101/i-dont-know-machine-learning-as-well-as-i-thought-i-did-kan</guid>
      <description>&lt;p&gt;Human Learning ML — Devlog #1&lt;/p&gt;

&lt;p&gt;Out of curiosity, I picked up ML and AI as the next tech stack I wanted to learn. After a month, I’m realising it’s probably going to take a year or more before I feel even minimally confident enough to put it on my resume.&lt;/p&gt;

&lt;p&gt;A little background: I did Andrew Ng’s Machine Learning Specialisation in college around 5–6 years ago. I built a fraud detection project, an image classification project, and even wrote a research paper titled “YOLOv3 Remote Sensing SAR Ship Image Detection.” Then I got a job as a Mobile Engineer (with a bit of backend work too) and slowly got busy with life.&lt;br&gt;&lt;br&gt;
Back then, it mostly felt like choosing a good enough ML algorithm based on the dataset and desired outcome. I didn’t see much beyond that at the time. But with the rise of LLMs, I got curious again and started reading &lt;em&gt;AI Engineering&lt;/em&gt; by &lt;em&gt;Chip Huyen&lt;/em&gt;, along with random blogs, &lt;em&gt;Andrej Karpathy&lt;/em&gt; videos, research papers, and other internet resources.&lt;/p&gt;

&lt;p&gt;I realised I had a lot of misconceptions, knowledge gaps, and even more curiosity.&lt;br&gt;&lt;br&gt;
The rest of this blog is about those things.&lt;/p&gt;

&lt;p&gt;One thing I started doing was drawing rough mental maps of how concepts connect together.&lt;br&gt;&lt;br&gt;
This was one of the first sketches I made while trying to understand what actually goes into a “foundation model.”&lt;/p&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%2Fnqw2ysz3yszsy0og7bat.jpeg" 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%2Fnqw2ysz3yszsy0og7bat.jpeg" alt="One of my early attempts at connecting together concepts like data, architectures, and foundation models." width="800" height="618"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;One of my early attempts at connecting together concepts like data, architectures, and foundation models.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Misconceptions:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Context: When someone says a foundation model needs context tokens to generate the next output token, I thought “context” only meant the input tokens we provide.&lt;br&gt;&lt;br&gt;
But that’s not true. That’s only the starting point. These input tokens are processed, additional context may be added via external tools like MCPs, and previously generated output tokens themselves also become context for the next token.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stateless: When we send prompts to a foundation model like ChatGPT, the information is not stored inside the model itself, i.e., the model does not permanently learn from it. It processes the prompt, generates an output, and moves on. Basically, they are stateless.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Self-Supervision: The so-called pre-training process of a foundation model does not rely heavily on human labellers because the model learns through self-supervision using massive amounts of internet data.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Knowledge Gaps
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Intuitions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Derivatives: I forgot the intuition for derivatives. They represent the "rate of change at a particular point" in a function. The rate of change, i.e., the slope, can be steep or shallow. That represents the magnitude of the change. The sign tells whether the change is increasing or decreasing.&lt;/li&gt;
&lt;li&gt; Dot Product: I have to look this up again.&lt;/li&gt;
&lt;li&gt; Attention Mechanism: Why does the transformer use the dot product between query and key vectors to score attention between tokens?&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Parameters and Model Size: I still struggle to intuitively understand why models with more parameters generally perform better. Since parameters are tied to the function the model learns, how does increasing parameter count improve learning capacity and reasoning ability?  &lt;/p&gt;

&lt;p&gt;I even started drawing out tiny toy examples to rebuild intuition around parameters, functions, and what models are actually learning.&lt;/p&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%2Fsgebvxheg2yfk4r0wd2n.jpeg" 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%2Fsgebvxheg2yfk4r0wd2n.jpeg" alt="Trying to rebuild intuition around parameters and functions." width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Trying to rebuild intuition around parameters and functions.&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;ML Concepts: Understanding where they fit into the bigger picture of machine learning. I need to revisit them again.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Activation Functions&lt;/li&gt;
&lt;li&gt; Feedforward&lt;/li&gt;
&lt;li&gt; RAG (Retrieval-Augmented Generation)&lt;/li&gt;
&lt;li&gt; Post-Training&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;

&lt;h3&gt;
  
  
  Things That Started Making Sense
&lt;/h3&gt;

&lt;p&gt;Things I was curious about and finally got answers to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;SSMs: A newer architecture focused on handling longer contexts more efficiently because transformer architectures (used in most modern LLMs) become expensive and memory-heavy with long contexts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hybrid Architectures: Models can mix layers and ideas from different architectures and mechanisms. For example, combining ideas from attention mechanisms and RNN-like architectures.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dataset: Quality of training data matters more than just quantity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Naming Convention: Model names often represent the number of parameters. In &lt;em&gt;Llama3-70B&lt;/em&gt;, 70B refers to the number of parameters.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The more concepts started making sense, the more new questions started appearing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Still Curious
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;What are companies actually using for chatbots, customer support, and AI assistants?&lt;br&gt;&lt;br&gt;
Are they building on top of existing foundation models through APIs, fine-tuning open-source models, or training things in-house?&lt;br&gt;&lt;br&gt;
And what does “in-house AI” actually mean inside startups or enterprises? What kind of work do those teams actually do day-to-day?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;How does post-training work for base models?&lt;br&gt;&lt;br&gt;
Do companies train the model again on additional data, or is the process more nuanced than that?&lt;br&gt;&lt;br&gt;
I tried drawing the pipeline based on my current understanding, but I still feel like I’m missing a lot of details around what actually happens during post-training.&lt;/p&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%2Flfo0uxa3hxizy1oel62h.jpeg" 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%2Flfo0uxa3hxizy1oel62h.jpeg" alt="My current mental model of pretraining → supervised fine-tuning → reinforcement learning." width="800" height="176"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;My current mental model of pre-training → supervised fine-tuning → reinforcement learning.&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How does RAG actually work internally?&lt;br&gt;&lt;br&gt;
Since context windows are limited, how does the system retrieve only the relevant pieces of information from huge datasets?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When using tools like Claude or Cursor, is every chat prompt an API call happening in real time?&lt;br&gt;&lt;br&gt;
And how do they stream responses word-by-word? Is it done through WebSockets or something else?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Why are models like Claude so good at coding tasks?&lt;br&gt;&lt;br&gt;
Is it because of post-training on coding datasets, reinforcement learning, tool usage, or something else?&lt;br&gt;&lt;br&gt;
Are there papers or engineering blogs explaining this in detail?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What does running a model on lower precision like FP8 or BF16 actually mean?&lt;br&gt;&lt;br&gt;
How does reducing precision still preserve model quality while improving performance?&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Starting ML again after 5–6 years has been humbling. Back then, I thought I had understood it — courses, projects, even a research paper. But coming back to it now made me realise how much I had forgotten, and how much deeper the field actually goes.&lt;br&gt;&lt;br&gt;
This time, I’m trying to understand what is actually happening underneath instead of just making the models work.&lt;/p&gt;

</description>
      <category>devlog</category>
      <category>machinelearning</category>
      <category>ai</category>
      <category>software</category>
    </item>
    <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 width="384" src="https://i.giphy.com/media/QX15lZJbifeQPzcNDt/giphy.gif" 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>
