<?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: Elian Ortega</title>
    <description>The latest articles on DEV Community by Elian Ortega (@elianortega).</description>
    <link>https://dev.to/elianortega</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%2F405494%2F424d3610-58c0-4343-9f5e-19c749f6d99c.jpg</url>
      <title>DEV Community: Elian Ortega</title>
      <link>https://dev.to/elianortega</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/elianortega"/>
    <language>en</language>
    <item>
      <title>🔁 asdf Flutter version manager (MacOS/ Linux)</title>
      <dc:creator>Elian Ortega</dc:creator>
      <pubDate>Fri, 08 Oct 2021 21:47:07 +0000</pubDate>
      <link>https://dev.to/elianortega/asdf-flutter-version-manager-macos-linux-4og0</link>
      <guid>https://dev.to/elianortega/asdf-flutter-version-manager-macos-linux-4og0</guid>
      <description>&lt;p&gt;Without a doubt, &lt;a href="https://flutter.dev/" rel="noopener noreferrer"&gt;Flutter&lt;/a&gt; is a framework that is constantly changing. And as developers, we need to be ready and have more than one version installed at the same time.&lt;/p&gt;

&lt;p&gt;One of the most famous solutions for this problem is &lt;a href="https://github.com/leoafarias/fvm" rel="noopener noreferrer"&gt;Flutter Version Manager by leofarias&lt;/a&gt;. I personally used this solution for several months, but I always had some problems with it.&lt;/p&gt;

&lt;p&gt;A few weeks ago I came across &lt;a href="https://asdf-vm.com/" rel="noopener noreferrer"&gt;asdf&lt;/a&gt;, which according to its documentation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;asdf&lt;/code&gt; is a tool version manager. All tool version definitions are contained within one file (&lt;code&gt;.tool-versions&lt;/code&gt;) which you can check in to your project's Git repository to share with your team, ensuring everyone is using the exact same versions of tools.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fb8m3ik8v8g7a1meend0q.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fb8m3ik8v8g7a1meend0q.gif" alt="https://media.giphy.com/media/3oKIPqsXYcdjcBcXL2/giphy-downsized-large.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In a nutshell, it allows us to handle multiple versions of different tools (which I found interesting as it could be useful for other tools like: &lt;code&gt;cocoapods&lt;/code&gt;,&lt;code&gt;ruby&lt;/code&gt;,&lt;code&gt;node.js&lt;/code&gt;, etc.) &lt;/p&gt;

&lt;h2&gt;
  
  
  How to use asdf with flutter?
&lt;/h2&gt;

&lt;p&gt;Official docs: &lt;a href="https://asdf-vm.com/guide/getting-started.html#_1-install-dependencies" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Install asdf
&lt;/h3&gt;

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

&lt;span class="c"&gt;# MacOS with Homebrew&lt;/span&gt;
brew &lt;span class="nb"&gt;install &lt;/span&gt;asdf

&lt;span class="c"&gt;# Linux&lt;/span&gt;
&lt;span class="c"&gt;# Check: https://asdf-vm.com/guide/getting-started.html#_1-install-dependencies&lt;/span&gt;


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  ASDF Flutter plugin
&lt;/h3&gt;

&lt;p&gt;Once asdf is installed, we have to install the asdf flutter plugin&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="c"&gt;# Installs flutter-plugin for asdf&lt;/span&gt;
asdf plugin-add flutter


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

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://github.com/oae/asdf-flutter" rel="noopener noreferrer"&gt;Github Repo: asdf flutter plugin&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  install/uninstall a version
&lt;/h3&gt;

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

&lt;span class="c"&gt;# List all available flutter versions&lt;/span&gt;
asdf list all flutter


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

&lt;/div&gt;

&lt;p&gt;Preview:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fiql8kn8mjtqju4igp2do.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fiql8kn8mjtqju4igp2do.png" alt="carbon"&gt;&lt;/a&gt; &lt;/p&gt;

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

&lt;span class="c"&gt;# Install a version &lt;/span&gt;
asdf &lt;span class="nb"&gt;install &lt;/span&gt;flutter &amp;lt;VERSION_NUMBER&amp;gt;

&lt;span class="c"&gt;# Example:&lt;/span&gt;
asdf &lt;span class="nb"&gt;install &lt;/span&gt;flutter 2.5.2-stable

&lt;span class="c"&gt;# to uninstall&lt;/span&gt;
asdf uninstall flutter &amp;lt;VERSION_NUMBER&amp;gt;


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  Local and global version
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="c"&gt;# Defines a global flutter version to be used &lt;/span&gt;
asdf global flutter &amp;lt;VERSION_NUMBER&amp;gt;

&lt;span class="c"&gt;# Defines a local flutter version to be used &lt;/span&gt;
asdf &lt;span class="nb"&gt;local &lt;/span&gt;flutter &amp;lt;VERSION_NUMBER&amp;gt;


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Export to $PATH
&lt;/h2&gt;

&lt;p&gt;To have access to the currently selected version, you need to export asdf flutter to  &lt;code&gt;$PATH&lt;/code&gt;.In my case, I added the following line to my &lt;code&gt;/.zshrc.&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;asdf where flutter&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;/bin"&lt;/span&gt;:&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;With this you will have access to the &lt;code&gt;flutter&lt;/code&gt; and &lt;code&gt;dart&lt;/code&gt; commands from any terminal 👍.&lt;/p&gt;

&lt;h2&gt;
  
  
  ... and dart?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;dart&lt;/code&gt; is included by default with the &lt;code&gt;asdf flutter plugin&lt;/code&gt;. However, sometimes you need a different &lt;code&gt;dart&lt;/code&gt; version. This can be accomplished by running the same commands mentioned above, but substituting &lt;code&gt;flutter&lt;/code&gt; with &lt;code&gt;dart&lt;/code&gt;. &lt;/p&gt;


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

&lt;p&gt;&lt;span class="c"&gt;# Install asdf-dart&lt;/span&gt;&lt;br&gt;
asdf plugin-add dart &lt;a href="https://github.com/patoconnor43/asdf-dart.git" rel="noopener noreferrer"&gt;https://github.com/patoconnor43/asdf-dart.git&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="c"&gt;# More info in: &lt;a href="https://github.com/PatOConnor43/asdf-dart" rel="noopener noreferrer"&gt;https://github.com/PatOConnor43/asdf-dart&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

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

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  As always...&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;You can share this article to help another developer to continue improving their productivity when writing applications with Flutter.&lt;/p&gt;

&lt;p&gt;There's a Spanish version of this article on Medium. You're welcome. 🇪🇸&lt;/p&gt;

&lt;p&gt;Also, if you liked this content, you can find even more and keep in contact with me on my socials:&lt;/p&gt;

&lt;p&gt;Also, if you liked this content, you can find even more and keep in contact with me on my socials:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/elianortega"&gt;dev.to&lt;/a&gt; - where you're reading this article.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/elianortega" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; - where are my code repositories in case you like the examples.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/NoScopeDevs" rel="noopener noreferrer"&gt;GitHub NoScope&lt;/a&gt; - donde están los repositorios de código en conjunto del canal de YouTube y directos de Twitch con Marcos.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.linkedin.com/in/elianortega/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; - where I connect professionally.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://twitter.com/ElianMOrtega" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; -  where I express my short thoughts and share my content.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.twitch.tv/noscopedevs" rel="noopener noreferrer"&gt;Twitch&lt;/a&gt; - where I do informal live shows from which I take clips with specific information.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/c/noscopedevs" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt; - where I publish the clips that come out of my lives.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;🇪🇸 Versión en español de este articulo &lt;a href="https://elianmortega.medium.com/asdf-flutter-version-manager-macos-linux-cd869fc0990b" rel="noopener noreferrer"&gt;aquí&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>flutter</category>
      <category>asdf</category>
    </item>
    <item>
      <title>How to start using Riverpod, StateNotifier and Freezed in your Flutter applications.</title>
      <dc:creator>Elian Ortega</dc:creator>
      <pubDate>Wed, 14 Apr 2021 15:55:27 +0000</pubDate>
      <link>https://dev.to/elianortega/how-to-start-using-riverpod-statenotifier-and-freezed-in-your-flutter-applications-181k</link>
      <guid>https://dev.to/elianortega/how-to-start-using-riverpod-statenotifier-and-freezed-in-your-flutter-applications-181k</guid>
      <description>&lt;p&gt;How to use the 3 tools together to manage the state of your application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://elian-mortega.medium.com/como-empezar-con-riverpod-statenotifier-freezed-a47402c772ea" rel="noopener noreferrer"&gt;Haz clic aquí para la versión en español&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;More and more we hear of &lt;code&gt;Riverpod&lt;/code&gt; as the new state management solution in Flutter. The big problem is that people trying to use it do not even know where to start.&lt;/p&gt;

&lt;p&gt;In this article I am going to focus on how a project can be structured using &lt;a href="https://pub.dev/packages/riverpod" rel="noopener noreferrer"&gt;Riverpod&lt;/a&gt;,&lt;a href="https://pub.dev/packages/state_notifier" rel="noopener noreferrer"&gt;StateNotifer&lt;/a&gt; and &lt;a href="https://pub.dev/packages/freezed" rel="noopener noreferrer"&gt;Freezed&lt;/a&gt; together to create the complete flow of state management.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are we going to build?
&lt;/h2&gt;

&lt;p&gt;We are going to build a jokes application, it's going to use the &lt;a href="https://v2.jokeapi.dev/" rel="noopener noreferrer"&gt;Jokes API&lt;/a&gt; to get a new programming joke and then show it in the screen. The  result will look something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FNoScopeDevs%2Friverpod_jokes_basic%2Fmain%2Fassets%2Freadme%2Fapp_result.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FNoScopeDevs%2Friverpod_jokes_basic%2Fmain%2Fassets%2Freadme%2Fapp_result.gif" alt="https://raw.githubusercontent.com/NoScopeDevs/riverpod_jokes_basic/main/assets/readme/app_result.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Basics
&lt;/h2&gt;

&lt;p&gt;I could make an explanation of each of these tools, but there is no need to reinvent the wheel. My friend  &lt;a href="https://twitter.com/MarcosJSevilla" rel="noopener noreferrer"&gt;Marcos Sevilla&lt;/a&gt;  has some excellent articles explaining these tools.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/marcossevilla/riverpod-rewriting-provider-359n"&gt;Riverpod article&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;A tool that allows us to inject dependencies and encapsulate a state and then listen to this state.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://dev.to/marcossevilla/statenotifier-an-improved-changenotifier-3f84"&gt;StateNotifier article&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;It is a “re-implementation” of ValueNotifier, with the difference that it does not depend on Flutter.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://dev.to/marcossevilla/how-to-generate-even-more-code-with-freezed-2ijg"&gt;Freezed article&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;It is a code generator for immutable classes.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Now that you know what each of these tools are and how they work, let's see how we can use them together as a state management solution.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ Before continuing it is important that you know the basics concepts of the tools so read the documentation!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now let's get started!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F6nsdezj7uw4dyxle751n.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F6nsdezj7uw4dyxle751n.gif" alt="https://media.giphy.com/media/Y3MbPtRn74uR3Ziq4P/source.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Folder Structure
&lt;/h2&gt;

&lt;p&gt;In order to maintain a clean code base, the folder structure is key, so let's start with the idea of separating our application by features. If you have used &lt;code&gt;flutter_bloc&lt;/code&gt;, you have seen that it is very common to create a bloc folder with its respective &lt;strong&gt;states,&lt;/strong&gt; &lt;strong&gt;events&lt;/strong&gt; and a &lt;strong&gt;views&lt;/strong&gt; folder for the UI part of our feature, something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FNoScopeDevs%2Friverpod_jokes_basic%2Fmain%2Fassets%2Freadme%2Fbloc_folder_structure.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FNoScopeDevs%2Friverpod_jokes_basic%2Fmain%2Fassets%2Freadme%2Fbloc_folder_structure.png" alt="https://raw.githubusercontent.com/NoScopeDevs/riverpod_jokes_basic/main/assets/readme/bloc_folder_structure.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Carpeta generada con la extensión de VS Code de bloc v5.6.0&lt;/p&gt;

&lt;p&gt;As you can see we have a &lt;strong&gt;feature&lt;/strong&gt; called &lt;strong&gt;jokes&lt;/strong&gt; in this you will find the logic and views of the jokes app. This structure may be familiar to many who have already used &lt;code&gt;flutter_bloc&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But before looking at the code let's see the structure we want to achieve using &lt;strong&gt;Riverpod&lt;/strong&gt;, &lt;strong&gt;StateNotifier&lt;/strong&gt; and &lt;strong&gt;Freezed&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FNoScopeDevs%2Friverpod_jokes_basic%2Fmain%2Fassets%2Freadme%2Friverpod_folder_structure.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FNoScopeDevs%2Friverpod_jokes_basic%2Fmain%2Fassets%2Freadme%2Friverpod_folder_structure.png" alt="https://raw.githubusercontent.com/NoScopeDevs/riverpod_jokes_basic/main/assets/readme/riverpod_folder_structure.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see that it is a very similar structure to the one proposed by &lt;strong&gt;flutter_bloc.&lt;/strong&gt; But in this case, because of how riverpod works we have the following files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;jokes_state.dart&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;This file is where we define the possible states that the &lt;strong&gt;StateNotifier&lt;/strong&gt; can emit. Commonly they are: &lt;strong&gt;initial&lt;/strong&gt;, &lt;strong&gt;loading&lt;/strong&gt;, &lt;strong&gt;data&lt;/strong&gt; and &lt;strong&gt;error&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;jokes_state.freezed.dart&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;This is a file that is generated with all the information of the classes that we define in &lt;code&gt;jokes_state.dart&lt;/code&gt;, we shouldn't worry that much about its content, since it is generated code.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;jokes_state_notifier.dart&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;This file contains the definition of the &lt;code&gt;JokesNotifier&lt;/code&gt;, which is an implementation of  &lt;strong&gt;StateNotifier. T&lt;/strong&gt;his will be the core of our state management, since in this class is where we define the methods that will be in charge of changing and emitting the new states when necessary.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;jokes_provider.dart&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;This file is where we define the different types of &lt;strong&gt;Providers&lt;/strong&gt; that we are going to use in this feature. In this case  we will need 2, the first is a common &lt;code&gt;Provider&lt;/code&gt; for the repository from where we will obtain a new joke and the second a &lt;code&gt;StateNotifierProvider&lt;/code&gt; that is a special provider for &lt;strong&gt;StateNotifiers&lt;/strong&gt; objects. Or in other words, we could say that this file is where the feature's dependency injection is done.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;But with this last point, what happens if we have 2 different features that use the same provider?&lt;/p&gt;

&lt;p&gt;Very simple, we can create a file where we are going to define global providers that may be used by several features at the same time. Something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fghkj0hdc82iz5e8ghtbm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fghkj0hdc82iz5e8ghtbm.png" alt="https://raw.githubusercontent.com/elian-ortega/Riverpod-StateNotifier-Freezed-Example/main/assets/shared_providers.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And if you've already read the documentation, you know it, but just in case I remind you that combining providers with riverpod is very simple.&lt;/p&gt;

&lt;p&gt;For example, let's imagine the scenario of a store where we define a &lt;code&gt;Provider&lt;/code&gt; for the payment methods (&lt;code&gt;PaymentMethods&lt;/code&gt;) and another provider for the &lt;code&gt;Checkout&lt;/code&gt;, in this case the &lt;code&gt;Checkout&lt;/code&gt; provider needs the &lt;code&gt;PaymentMethods&lt;/code&gt; provider to be able to work and thanks to the &lt;code&gt;ProviderReference&lt;/code&gt; parameter available when creating a new provider with riverpod, creating the relationship It is very simple:&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;///PaymentMethods Provider&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;_paymentMethodsProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PaymentMethods&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;ProviderReference&lt;/span&gt; &lt;span class="n"&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;PaymentMethods&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;///CheckOut Provider&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;checkoutProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Checkout&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;ProviderReference&lt;/span&gt; &lt;span class="n"&gt;ref&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;Checkout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;paymentMethodsProvider:&lt;/span&gt; &lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_paymentMethodsProvider&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;blockquote&gt;
&lt;p&gt;📖 If you still do not understand this last part very well, I recommend you reading the articles of the tools that I left at the beginning, here.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's see the code 🔥&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fdoqnnodxz446i2wvgcah.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fdoqnnodxz446i2wvgcah.gif" alt="https://media.giphy.com/media/LmNwrBhejkK9EFP504/source.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Project setup
&lt;/h2&gt;

&lt;p&gt;You may laugh at this step, but you would be amazed at how many times it is forgotten. To use riverpod you have to add a &lt;code&gt;ProviderScope&lt;/code&gt; widget as the root of our application, this allows the communication of providers and is required to use riverpod.&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;///main.dart&lt;/span&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="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter_riverpod/flutter_riverpod.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:riverpod_jokes_basic/src/app.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&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;runApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;ProviderScope&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;RiverpodJokesApp&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;Personally, I like to separate the &lt;strong&gt;main.dart&lt;/strong&gt; from the rest of the application and create an &lt;strong&gt;app.dart&lt;/strong&gt; file that contains the root of the application and any extra configuration that is needed.&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;///app.dart&lt;/span&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="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:riverpod_jokes_basic/src/features/jokes/views/jokes_page.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;RiverpodJokesApp&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="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;MaterialApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="s"&gt;'Flutter Demo'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;theme:&lt;/span&gt; &lt;span class="n"&gt;ThemeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;primarySwatch:&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;home:&lt;/span&gt; &lt;span class="n"&gt;JokesPage&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;And just like that, we are ready to start using riverpod. Remember to include the dependencies in the &lt;strong&gt;pubspec.yaml&lt;/strong&gt; file*&lt;em&gt;,&lt;/em&gt;* as of the moment I write this article they are:&lt;/p&gt;

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

&lt;span class="c1"&gt;# pubspec.yaml&lt;/span&gt;

&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;riverpod_jokes_basic&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;A new Flutter project.&lt;/span&gt;

&lt;span class="na"&gt;publish_to&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;none'&lt;/span&gt;

&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1.0.0+1&lt;/span&gt;

&lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;sdk&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;gt;=2.12.0&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;lt;3.0.0"&lt;/span&gt;

&lt;span class="na"&gt;dependencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;flutter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;sdk&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;flutter&lt;/span&gt;
  &lt;span class="na"&gt;cupertino_icons&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^1.0.2&lt;/span&gt;
  &lt;span class="na"&gt;dio&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^4.0.0&lt;/span&gt;
  &lt;span class="na"&gt;equatable&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^2.0.0&lt;/span&gt;
  &lt;span class="na"&gt;flutter_riverpod&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^0.14.0+1&lt;/span&gt;
  &lt;span class="na"&gt;freezed_annotation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^0.14.1&lt;/span&gt;

&lt;span class="na"&gt;dev_dependencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;flutter_test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;sdk&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;flutter&lt;/span&gt;
  &lt;span class="na"&gt;build_runner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^1.12.2&lt;/span&gt;
  &lt;span class="na"&gt;freezed&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^0.14.1+2&lt;/span&gt;
  &lt;span class="na"&gt;json_serializable&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^4.1.0&lt;/span&gt;

&lt;span class="na"&gt;flutter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

  &lt;span class="na"&gt;uses-material-design&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Models
&lt;/h2&gt;

&lt;p&gt;Before we can code the logic side of the application, we need to create the models that represent the objects from the API. In this case, we are going to be guided by the documentation provided by Jokes API, where they tell us that the response format looks like this:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;///&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;JOKES&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;API&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Response&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Programming"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"twopart"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"setup"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"How many programmers does it take to screw in a light bulb?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"delivery"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"None. It's a hardware problem."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"flags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"nsfw"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"religious"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"political"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"racist"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"sexist"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"explicit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"safe"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"lang"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"en"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;


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

&lt;/div&gt;

&lt;p&gt;Just by looking at the response format, we can identify the 2 models that we are going to use. The first one is a model for the possible flags of the joke, we will call it &lt;code&gt;FlagsModel&lt;/code&gt; and another model for the whole joke that we will call &lt;code&gt;JokesModel&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;These objects use &lt;strong&gt;equatable&lt;/strong&gt; and &lt;strong&gt;json_serializable&lt;/strong&gt; to generate the &lt;code&gt;fromJson()&lt;/code&gt; and &lt;code&gt;toJson()&lt;/code&gt; methods.&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;// flags_model.dart&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:equatable/equatable.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:freezed_annotation/freezed_annotation.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;'flags_model.g.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@JsonSerializable&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;FlagsModel&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;Equatable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;FlagsModel&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;explicit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nsfw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;political&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;racist&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;religious&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sexist&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;//Json Serializable&lt;/span&gt;
  &lt;span class="kd"&gt;factory&lt;/span&gt; &lt;span class="n"&gt;FlagsModel&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;(&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="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;_$FlagsModelFromJson&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="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="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_$FlagsModelToJson&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="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;explicit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;nsfw&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;political&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;racist&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;religious&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;sexist&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;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;?&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;props&lt;/span&gt; &lt;span class="o"&gt;=&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;explicit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;nsfw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;political&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;racist&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;religious&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;sexist&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// jokes_model.dart&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:equatable/equatable.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:freezed_annotation/freezed_annotation.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'./flags_model.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;'joke_model.g.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@JsonSerializable&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;JokeModel&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;Equatable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;JokeModel&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;safe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;delivery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;//Json Serializable&lt;/span&gt;
  &lt;span class="kd"&gt;factory&lt;/span&gt; &lt;span class="n"&gt;JokeModel&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;(&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="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;_$JokeModelFromJson&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="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="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_$JokeModelToJson&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="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;category&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;delivery&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;FlagsModel&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;safe&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;type&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;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;?&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;props&lt;/span&gt; &lt;span class="o"&gt;=&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;category&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;delivery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;safe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;type&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;Once these 2 classes are created, it is necessary to run the &lt;code&gt;build_runner&lt;/code&gt; commands since &lt;strong&gt;json_serializable&lt;/strong&gt; must generate the parsing methods of the classes.&lt;/p&gt;

&lt;p&gt;We run the following commands:&lt;/p&gt;

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

&lt;span class="c"&gt;# When the project depends on Flutter&lt;/span&gt;

flutter pub run build_runner build

&lt;span class="c"&gt;# In project is pure dart&lt;/span&gt;

pub run build_runner build


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

&lt;/div&gt;

&lt;p&gt;With this all syntax errors should disappear, and we can get to the next step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Repository
&lt;/h2&gt;

&lt;p&gt;On this occasion I am not going to focus much on this step or any clean architecture layer/component, since it is not the main goal. If you want to see more examples or documentation of clean architecture and its components you can check my networks where I have other articles, code repositories and videos talking about these concepts.&lt;/p&gt;

&lt;p&gt;The reason for creating the repository with an interface, of course good coding practices, but also that you can see how the dependency injection with interfaces can be done when we create the providers.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;jokes_repository.dart&lt;/strong&gt; contains the &lt;code&gt;IJokesRepository&lt;/code&gt; interface and &lt;code&gt;JokesRepository&lt;/code&gt; which is the implementation. These only have a &lt;code&gt;Future&amp;lt;JokeModel&amp;gt; getJoke();&lt;/code&gt; method that makes an API call to get a new joke. If &lt;strong&gt;the response is successful it returns the joke, otherwise an exception is thrown.&lt;/strong&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;/// jokes_repository.dart&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:dio/dio.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:riverpod_jokes_basic/src/features/jokes/data/models/joke_model.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;IJokesRepository&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;JokeModel&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getJoke&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;JokesRepository&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="n"&gt;IJokesRepository&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;_dioClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Dio&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;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'https://v2.jokeapi.dev/joke/Programming?type=twopart'&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;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;JokeModel&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getJoke&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;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;result&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;_dioClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&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;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;statusCode&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;200&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;JokeModel&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;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&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="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="n"&gt;Exception&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;catch&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="k"&gt;throw&lt;/span&gt; &lt;span class="n"&gt;Exception&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;
  
  
  States using Freezed
&lt;/h2&gt;

&lt;p&gt;In this case, our feature of generating random numbers is not very complex, the objective is to simulate the call to an API, and react to the different states in the UI. So, we are going to have &lt;strong&gt;4 states: initial, loading (loading), data&lt;/strong&gt; when we already have the new joke and &lt;strong&gt;error&lt;/strong&gt; to give feedback to the user about what is happening.&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;/// jokes_state.dart&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:freezed_annotation/freezed_annotation.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:riverpod_jokes_basic/src/features/jokes/data/models/joke_model.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;'jokes_state.freezed.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;///Extension Method for easy comparison&lt;/span&gt;
&lt;span class="n"&gt;extension&lt;/span&gt; &lt;span class="n"&gt;JokesGetters&lt;/span&gt; &lt;span class="kd"&gt;on&lt;/span&gt; &lt;span class="n"&gt;JokesState&lt;/span&gt; &lt;span class="p"&gt;{&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;isLoading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;_JokesStateLoading&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;@freezed&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;JokesState&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;_$JokesState&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;///Initial&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="kd"&gt;factory&lt;/span&gt; &lt;span class="n"&gt;JokesState&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;initial&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_JokesStateInitial&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;///Loading&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="kd"&gt;factory&lt;/span&gt; &lt;span class="n"&gt;JokesState&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_JokesStateLoading&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;///Data&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="kd"&gt;factory&lt;/span&gt; &lt;span class="n"&gt;JokesState&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="n"&gt;JokeModel&lt;/span&gt; &lt;span class="n"&gt;joke&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_JokesStateData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;///Error&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="kd"&gt;factory&lt;/span&gt; &lt;span class="n"&gt;JokesState&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_JokesStateError&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;Also, we added an extension method to simplify the comparison made to know if the current state is loading.&lt;/p&gt;

&lt;p&gt;Once we have defined the structure of the states with the respective &lt;strong&gt;Freezed&lt;/strong&gt; &lt;strong&gt;annotations&lt;/strong&gt;, we must run a command to create the &lt;strong&gt;jokes_state.freezed.dart&lt;/strong&gt; file with generated code.&lt;/p&gt;

&lt;p&gt;In the terminal:&lt;/p&gt;

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

&lt;span class="c"&gt;# In this case our project depend on flutter&lt;/span&gt;
&lt;span class="c"&gt;# so we run&lt;/span&gt;

flutter pub run build_runner build

&lt;span class="c"&gt;# If the project was pure dart we run&lt;/span&gt;

pub run build_runner build


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

&lt;/div&gt;

&lt;p&gt;With this the new file will be generated resolving the syntax error from the states file.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ The &lt;strong&gt;jokes_state.freezed.dart&lt;/strong&gt; code is generated so don't be stressed or intimidated if you don't understand it, it shouldn't be modified.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Implementing the StateNotifier
&lt;/h2&gt;

&lt;p&gt;As I mentioned earlier, this is the core of our state management.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F48gt2iktkfaljmnyjpzq.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F48gt2iktkfaljmnyjpzq.gif" alt="https://media.giphy.com/media/xUPGchIuMGVrjvVrDq/source.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this class is where we will make the calls to the repository, and we will assign the states so that they are notified to the components in the UI.&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;/// jokes_state_notifier.dart&lt;/span&gt;

&lt;span class="kn"&gt;part of&lt;/span&gt; &lt;span class="s"&gt;'jokes_provider.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;JokesNotifier&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StateNotifier&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;JokesState&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;JokesNotifier&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="n"&gt;IJokesRepository&lt;/span&gt; &lt;span class="n"&gt;jokesRepository&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="n"&gt;_jokesRepository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jokesRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;super&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;JokesState&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;initial&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;IJokesRepository&lt;/span&gt; &lt;span class="n"&gt;_jokesRepository&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;getJoke&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;state&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;JokesState&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;loading&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;joke&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;_jokesRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getJoke&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;JokesState&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;joke:&lt;/span&gt; &lt;span class="n"&gt;joke&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;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;JokesState&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Error!'&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;You can see that the first thing we do is in the &lt;code&gt;super()&lt;/code&gt; method of the class we assign the first state to &lt;code&gt;JokesState.initial()&lt;/code&gt;. Then, we only have a &lt;code&gt;getJoke()&lt;/code&gt; method that makes a call to the repository within a &lt;code&gt;try {} catch {}&lt;/code&gt; because as we saw previously, in some scenarios we are going to throw an exception. Based on this we will assign the new state to either &lt;code&gt;state = JokesState.data(joke: joke);&lt;/code&gt; &lt;strong&gt;when the API call is successfull&lt;/strong&gt; or &lt;code&gt;state = JokesState.error('Error!');&lt;/code&gt; when an exception is thrown and caught by the &lt;code&gt;catch()&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exposing providers and injecting dependencies
&lt;/h2&gt;

&lt;p&gt;Up to this point we have already created all the necessary components for the application logic to work. Now we must create 2 providers, first the &lt;strong&gt;Providers that inject the dependencies&lt;/strong&gt; in this case of the &lt;code&gt;JokesRepository&lt;/code&gt; with their respective &lt;strong&gt;interface&lt;/strong&gt; and second the &lt;strong&gt;Provider that expose the StateNotifier&lt;/strong&gt; in this case a &lt;strong&gt;StateNotifierProvider&lt;/strong&gt; that exposes the &lt;code&gt;JokesNotifier&lt;/code&gt; so that we can react to changes in states in the UI.&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;/// jokes_provider.dart&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter_riverpod/flutter_riverpod.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:riverpod_jokes_basic/src/features/jokes/data/repositories/jokes_repository.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'jokes_state.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;export&lt;/span&gt; &lt;span class="s"&gt;'jokes_state.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;'jokes_state_notifier.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;///Dependency Injection&lt;/span&gt;

&lt;span class="c1"&gt;//* Logic / StateNotifier&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;jokesNotifierProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StateNotifierProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;JokesNotifier&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;JokesState&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;ref&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;JokesNotifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;jokesRepository:&lt;/span&gt; &lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_jokesRepositoryProvider&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;//* Repository&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;_jokesRepositoryProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IJokesRepository&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;ref&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;JokesRepository&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;You can see that as I showed you previously in the &lt;strong&gt;PaymentMethods/Checkout&lt;/strong&gt; example, combining the providers is very simple, in this case we use the &lt;code&gt;ProviderReference (ref)&lt;/code&gt; &lt;strong&gt;to inject the dependency&lt;/strong&gt; that the &lt;code&gt;JokesNotifier&lt;/code&gt; has of the repository.&lt;/p&gt;

&lt;p&gt;Some might wonder why I declare &lt;code&gt;_jokesRepositoryProvider&lt;/code&gt; as a private variable? This is simply for good practices, with this you avoid making the mistake of making calls directly to the repository from the UI.&lt;/p&gt;

&lt;p&gt;With this we have concluded the implementation of all the necessary logic components for this application. Now we only have to implement the UI and react to the states.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reacting to states in the UI
&lt;/h2&gt;

&lt;p&gt;In this case, to simplify the example we only have one page in the UI. But before, I show you the code I want to emphasize 2 important points.&lt;/p&gt;

&lt;p&gt;Obviously remember to read the documentation, but just to remind you:&lt;/p&gt;

&lt;h3&gt;
  
  
  How to call a method on the StateNotifierProvider
&lt;/h3&gt;

&lt;p&gt;If you only want to call one method, in this case we need to call the &lt;code&gt;getJoke()&lt;/code&gt; method of the &lt;strong&gt;StateNotifier&lt;/strong&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;/// To call a method &lt;/span&gt;
&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;providerVariable&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;notifier&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;methodToCall&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;/// In our case to call the state notifier&lt;/span&gt;
&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jokesNotifierProvider&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;notifier&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getJoke&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  How to listen to changes in states
&lt;/h3&gt;

&lt;p&gt;If you want to listen to the state changes emitted by a &lt;strong&gt;StateNotifier&lt;/strong&gt; there are different ways, but the simplest is to use a &lt;code&gt;ConsumerWidget&lt;/code&gt; this gives us access to a property called watch of type &lt;code&gt;ScopedReader&lt;/code&gt; with this we can listen to the different state changes of the wanted provider.&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;/// Using a ConsumerWidget&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NewWidget&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;ConsumerWidget&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="n"&gt;ScopedReader&lt;/span&gt; &lt;span class="n"&gt;watch&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;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;randomNumberNotifierProvider&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="c1"&gt;///Here you can do whatever you want with the state&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 our case it is even simpler because when we use freezed to create states we have access to the &lt;code&gt;when ()&lt;/code&gt; method, this allows us to react to each of the states more easily avoiding the problem of many &lt;code&gt;if - else&lt;/code&gt; conditions in the code .&lt;/p&gt;

&lt;p&gt;For this implementation we could have something like this:&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;_JokeConsumer&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;ConsumerWidget&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="n"&gt;ScopedReader&lt;/span&gt; &lt;span class="n"&gt;watch&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;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jokesNotifierProvider&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;state&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;when&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;initial:&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;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Press the button to start'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;loading:&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;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;CircularProgressIndicator&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
      &lt;span class="nl"&gt;data:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;joke&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;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;${joke.setup}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;${joke.delivery}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;error:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&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;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Error Occured!'&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;ConsumerWidget&lt;/code&gt; return a different widget for each of the different states. &lt;/p&gt;

&lt;p&gt;With this  we are ready to create the page for our application: &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;/// jokes_page.dart&lt;/span&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="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter_riverpod/flutter_riverpod.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:riverpod_jokes_basic/src/features/jokes/logic/jokes_provider.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;///JokesPage&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;JokesPage&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="c1"&gt;///JokesPage constructor&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;JokesPage&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="c1"&gt;///JokesPage [routeName]&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;routeName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'JokesPage'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;///Router for JokesPage&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Route&lt;/span&gt; &lt;span class="n"&gt;route&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;MaterialPageRoute&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="nl"&gt;builder:&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="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;JokesPage&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="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Riverpod Jokes'&lt;/span&gt;&lt;span class="p"&gt;),&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;Padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;padding:&lt;/span&gt; &lt;span class="n"&gt;EdgeInsets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;symmetric&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;horizontal:&lt;/span&gt; &lt;span class="mf"&gt;20.0&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;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="n"&gt;_JokeConsumer&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;SizedBox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;height:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;_ButtonConsumer&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;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;_JokeConsumer&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;ConsumerWidget&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="n"&gt;ScopedReader&lt;/span&gt; &lt;span class="n"&gt;watch&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;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jokesNotifierProvider&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;state&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;when&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;initial:&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;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;'Press the button to start'&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="nl"&gt;loading:&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;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;CircularProgressIndicator&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;data:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;joke&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;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;${joke.setup}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;${joke.delivery}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;error:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&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;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Error Occured!'&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;_ButtonConsumer&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;ConsumerWidget&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="n"&gt;ScopedReader&lt;/span&gt; &lt;span class="n"&gt;watch&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;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jokesNotifierProvider&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;ElevatedButton&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="s"&gt;'Press me to get a joke'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;onPressed:&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isLoading&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="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jokesNotifierProvider&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;notifier&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getJoke&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="kc"&gt;null&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;And this would be the result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fi7liv9bhhoacti0tx1fh.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fi7liv9bhhoacti0tx1fh.gif" alt="https://raw.githubusercontent.com/elian-ortega/Riverpod-StateNotifier-Freezed-Example/main/assets/functionality.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's not the prettiest UI in the world, but that wasn't the goal, it was learning how to use riverpod, freezed, and statenotifier together as a state manager.&lt;/p&gt;

&lt;p&gt;This is a fairly basic example if you want to see an example with a complete clean architecture setup I leave you these links:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/NoScopeDevs/flutter_jokes" rel="noopener noreferrer"&gt;Jokes application created with riverpod following clean architecture principles&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/NoScopeDevs/covid_19_clean_scope_minimal" rel="noopener noreferrer"&gt;App with COVID 19 API and minimal architecture&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/elian-ortega/mobile-test/tree/master/qr_generator_flutter" rel="noopener noreferrer"&gt;Qr generator application with testing flutter_bloc and riverpod implementations + clean architecture&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the future I plan to share an article on how to do the testing and other things.&lt;/p&gt;

&lt;h3&gt;
  
  
  As always...
&lt;/h3&gt;

&lt;p&gt;Thanks to my friend  &lt;a href="https://twitter.com/MarcosJSevilla" rel="noopener noreferrer"&gt;Marcos Sevilla&lt;/a&gt; for this outro 😂, he also shares great content so here is his  &lt;a href="https://twitter.com/MarcosJSevilla" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; if you want to stay tuned of the content.&lt;/p&gt;

&lt;p&gt;You can share this article to help another developer to continue improving their productivity when writing applications with Flutter.&lt;/p&gt;

&lt;p&gt;There's a Spanish version of this article on Medium. &lt;a href="https://elian-mortega.medium.com/como-empezar-con-riverpod-statenotifier-freezed-a47402c772ea" rel="noopener noreferrer"&gt;Click here.&lt;/a&gt; You're welcome. 🇪🇸&lt;/p&gt;

&lt;p&gt;Also, if you liked this content, you can find even more and keep in contact with me on my socials:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/elianortega"&gt;dev.to&lt;/a&gt; - where you're reading this article.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/elian-ortega" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; - where are my code repositories in case you like the examples.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/NoScopeDevs" rel="noopener noreferrer"&gt;GitHub NoScope&lt;/a&gt; - where you can find the code repositories used in the YouTube and Twitch channels.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.linkedin.com/in/elian-ortega/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; - where I connect professionally.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://elian-mortega.medium.com/" rel="noopener noreferrer"&gt;Medium&lt;/a&gt; - where I publish my Spanish articles.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://twitter.com/ElianMOrtega" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; -  where I express my short thoughts and share my content.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.twitch.tv/noscopedevs" rel="noopener noreferrer"&gt;Twitch&lt;/a&gt; - where I do informal live shows from which I take clips with specific information.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/c/noscopedevs" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt; - where I publish the clips that come out of my lives.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>flutter</category>
      <category>riverpod</category>
      <category>provider</category>
      <category>dart</category>
    </item>
    <item>
      <title>Cleaner Flutter Vol. 5: Establishing Use Cases</title>
      <dc:creator>Elian Ortega</dc:creator>
      <pubDate>Sun, 31 Jan 2021 17:18:38 +0000</pubDate>
      <link>https://dev.to/elianortega/vol-2-solid-rules-in-dart-4154</link>
      <guid>https://dev.to/elianortega/vol-2-solid-rules-in-dart-4154</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Before starting: Previous Volume &lt;a href="https://dev.to/marcossevilla/cleaner-flutter-vol-4-hiring-repositories-5bpa"&gt;Cleaner Flutter Vol. 4: Hiring Repositories&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hello and welcome to the last volume where we will talk about the domain layer of the Clean Architecture proposal. Last time we talked about a fundamental part: the repositories, which allow us to create the communication of our software with the outside world.&lt;/p&gt;

&lt;p&gt;On this occasion, with the &lt;strong&gt;use cases&lt;/strong&gt; we are going to achieve independence from the specific interactions of the user with the system, using use cases and thus obtain maintainable, reusable code that truly meets the needs of the business.&lt;/p&gt;

&lt;p&gt;But before we get into technical matters, it is important that we remember that there are 2 perspectives: a developer's and a business perspective of the product. This differentiation is a very important topic, since by being clear about the objectives of the product we can develop software in a better way.&lt;/p&gt;

&lt;p&gt;Remember that all software products should first go through a process where their requirements and the interactions of a user with the software product are defined, whether this is a &lt;code&gt;login&lt;/code&gt;,&lt;code&gt;add an object to a shopping cart&lt;/code&gt;, or &lt;code&gt;process a payment&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Ok,  let's get into it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are use cases?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;In uncle Bobs words ...&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The software in this layer contains the application-specific business rules. These encapsulate and implement all the use cases of the system.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I remind you that the use cases mentioned in the definition do not refer coding part or module, but to the use cases that came from de planning phase of the project.  &lt;/p&gt;

&lt;p&gt;Each event is an interaction of the user with the system and we can call this a use case. As this is also a buisness concept the most common way of the displaying the use cases of the system is by the use case graph, that looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fybk4zjcsm41mqhaw0k26.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fybk4zjcsm41mqhaw0k26.png" alt="https://miro.medium.com/max/643/0*D5fgzZp_5AeUFkKP.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From: &lt;a href="https://warren2lynch.medium.com/use-case-tutorial-for-dummies-8cf426043710" rel="noopener noreferrer"&gt;https://warren2lynch.medium.com/use-case-tutorial-for-dummies-8cf426043710&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this we have objects like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Actor:&lt;/strong&gt; Users who interact with the system.(might be another software too)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use case:&lt;/strong&gt; How the actor uses the system to fulfill some functionality.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Relationships:&lt;/strong&gt; The relationship between the actors and the use cases&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The example shows some use cases for a passenger at an airport. Which, as I mentioned before, is the user's interactions with the system, in this case the logic of an airport.&lt;/p&gt;

&lt;p&gt;If you want to read more into these diagrams and their components, here is an article for you*&lt;em&gt;: &lt;a href="https://warren2lynch.medium.com/use-case-tutorial-for-dummies-8cf426043710" rel="noopener noreferrer"&gt;Use cases for dummies.&lt;/a&gt;&lt;/em&gt;*&lt;/p&gt;

&lt;h2&gt;
  
  
  In the code…
&lt;/h2&gt;

&lt;p&gt;In my experience, I have noticed that the use case layer is usually bypassed and replaced using methods directly in the software's business logic. But when we implement it we achieve better decoupling and other advantages.&lt;/p&gt;

&lt;p&gt;By adding the use cases layer the folder structure for the domain layer would look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Flkt9fzoqj3ddiy8b39pd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Flkt9fzoqj3ddiy8b39pd.png" alt="Folder Structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The principles (SOLID)...
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Simpler repositories.&lt;/strong&gt; When we create the use cases, we manage to facilitate communication with the repositories and we make sure to have better abstractions that meet the specific objective of that use case, and as we saw in previous articles, with this we comply with the &lt;strong&gt;single responsibility principle&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We use interfaces, not implementations.&lt;/strong&gt; In use cases we are normally going to depend on a repository, which rather must be an interface,this way we would be complying with the &lt;strong&gt;Liskov substitution principle&lt;/strong&gt;, since we could replace the repository with any other that implements the same interface and this will not affect the base logic of our use case.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation in Dart
&lt;/h2&gt;

&lt;p&gt;Like any of the components we've talked about throughout the series, each can be implemented in many ways. This time with the use cases we are going to use one of Dart's not very well known features.&lt;/p&gt;

&lt;p&gt;In Dart there is something called &lt;strong&gt;callable classes.&lt;/strong&gt; This allows us to use the instance of a class as if it were a function. To achieve this, all we have to do is implement the &lt;code&gt;call()&lt;/code&gt; method inside the class.&lt;/p&gt;

&lt;p&gt;We get something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F74pdlyzvifonqdtd9hw1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F74pdlyzvifonqdtd9hw1.png" alt="https://github.com/elian-ortega/use_cases_article/blob/main/assets/callable_class_example.png?raw=true"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using this Dart feature, we can create a class for each of our use cases and implement the call method with the respective functionality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's put the pieces together
&lt;/h2&gt;

&lt;p&gt;With all the information we have, we can already see an example  with all the pieces that we have carried so far: entities, repositories and use cases.&lt;/p&gt;

&lt;p&gt;The code is simplified to facilitate the example. I also remind you that in order to understand the examples it is important that you have read the previous articles. I leave the previous one: &lt;a href="https://medium.com/comunidad-flutter/un-flutter-m%C3%A1s-limpio-vol-4-contratando-repositorios-c604d38b102a" rel="noopener noreferrer"&gt;Vol 4: Contratando Repositorios&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let's imagine a very simple case of a &lt;code&gt;signIn&lt;/code&gt;, for this we are going to have a user entity and a repository interface that contains a method to make the &lt;code&gt;signIn&lt;/code&gt; using an email and password.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F3ckp5zlyym306p4o7w4h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F3ckp5zlyym306p4o7w4h.png" alt="https://github.com/elian-ortega/use_cases_article/blob/main/assets/user_repo3.png?raw=true"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is where many developers decide not to implement the use case layer, so they call the repositories directly from the application's business logic.&lt;/p&gt;

&lt;p&gt;But since we are using use cases, we create a &lt;code&gt;SignInUser&lt;/code&gt; class which will be our use case. This will have a dependency on the &lt;code&gt;AuthRepositoryInterface&lt;/code&gt;, then we implement the&lt;code&gt;call ()&lt;/code&gt;method and call&lt;code&gt;signIn ()&lt;/code&gt;. And so we have a use case with sole responsibility and decouple the repositories from the business logic (state handler).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F3gjt3p7sbep10d1i65gl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F3gjt3p7sbep10d1i65gl.png" alt="https://github.com/elian-ortega/use_cases_article/blob/main/assets/sing_in_use_case.png?raw=true"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that it does not matter who wins the endless battle of which is the best state manager, since it does not matter which one we select, or if we even decide to change, this does not affect our implementation at all.&lt;/p&gt;

&lt;p&gt;This example is quite simple, but for the moment what we are trying to do is understand each of the components that are part of this Clean Architecture proposal. Later we will make examples and videos applying all the theory with production code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F7axxeef6qlzso14h8mcq.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F7axxeef6qlzso14h8mcq.gif" alt="https://media.giphy.com/media/fnDY3C9MKukcER71r7/giphy.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  As always ...
&lt;/h2&gt;

&lt;p&gt;If you learned something new, remember to leave your feedback and share with your fellow developers friends so that we continue to improve as a community and develop quality applications using Flutter.&lt;/p&gt;

&lt;p&gt;For any questions and more content you can contact me through my social media:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/elian-ortega" rel="noopener noreferrer"&gt;GitHub,&lt;/a&gt; &lt;a href="https://www.linkedin.com/in/elian-ortega/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, &lt;a href="https://twitter.com/ElianOrtegaNCA" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, &lt;a href="https://www.youtube.com/channel/UCPz6bJ3DptMMXu7_hMb1oJQ" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>architecture</category>
      <category>dart</category>
      <category>clean</category>
    </item>
    <item>
      <title>Cleaner Flutter Vol. 2: SOLID Principles</title>
      <dc:creator>Elian Ortega</dc:creator>
      <pubDate>Sun, 17 Jan 2021 15:02:01 +0000</pubDate>
      <link>https://dev.to/elianortega/vol-2-solid-rules-in-dart-2e6m</link>
      <guid>https://dev.to/elianortega/vol-2-solid-rules-in-dart-2e6m</guid>
      <description>&lt;p&gt;💡 Recommendation: Return to this article as many times as necessary to clarify the following volumes, as there are concepts that complement these.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Previous Volume: &lt;a href="https://dev.to/marcossevilla/cleaner-flutter-vol-1-intro-to-clean-mo6"&gt;Cleaner Flutter Vol. 1: Intro to CLEAN&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next Volume: &lt;a href="https://dev.to/marcossevilla/cleaner-flutter-vol-3-dominating-entities-bk4"&gt;Cleaner Flutter Vol. 3: Dominating Entities&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After starting in the world of programming we all reach a point where we have to look back on the road and review some of the lines of code that we have written, either 1 day ago to remember an idea or years ago to review the implementation of any module of our software.&lt;/p&gt;

&lt;p&gt;Many times in these glances at the code of the past we come across a list of problems such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Having to search among many files for the answer to what we are looking for.&lt;/li&gt;
&lt;li&gt;Not understanding the code we wrote.&lt;/li&gt;
&lt;li&gt;Not understanding the code we write.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.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%2Femo0svfujqmj1t7h89oc.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Femo0svfujqmj1t7h89oc.gif" alt="https://media.giphy.com/media/GPQL5xsaunjmGcVqLn/giphy.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These problems start since we start a project because we do not spend enough time to have a clear idea not only of what we are going to do, but also of how we are going to do it.&lt;/p&gt;

&lt;p&gt;We have to develop code imagining what would happen if I return in 2 years to review it, this ability to program clean and understandable code is essential to facilitate development, especially if you work in a team.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is SOLID?
&lt;/h1&gt;

&lt;p&gt;SOLID is the acronym for a set of principles that help us develop more maintainable code that also allows easy extension without compromising code already developed.&lt;/p&gt;

&lt;p&gt;In other words ...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Write more code without damaging what already works.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We can even see them as a set of guidelines to follow. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic.wikia.nocookie.net%2Ffairlyoddparents%2Fimages%2F1%2F1e%2FDa_Rules.png%2Frevision%2Flatest%3Fcb%3D20180503070000%26path-prefix%3Den" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic.wikia.nocookie.net%2Ffairlyoddparents%2Fimages%2F1%2F1e%2FDa_Rules.png%2Frevision%2Flatest%3Fcb%3D20180503070000%26path-prefix%3Den" alt="Da rules book"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we are going to explore each of the principles, which can be applied to any programming language, but I am going to cover them using Dart language since it is the language used by the Flutter framework. &lt;/p&gt;

&lt;p&gt;Before continuing it is important to note that these were first introduced by Uncle Bob, I leave you a link in case you want to see his explanation: &lt;a href="https://www.youtube.com/watch?v=zHiWqnTWsn4&amp;amp;t=1154s" rel="noopener noreferrer"&gt;SOLID Principles Uncle Bob&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  S: Single Responsibility Principle
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;A class must have one, and only one, reason to change.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To explain this principle we can imagine a messy room, as we have all had it at some point, perhaps even now that you are reading this.&lt;/p&gt;

&lt;p&gt;But the truth is that within this, everything has its place and everything should be in its designated place.&lt;br&gt;
To put the analogy aside, this principle tells us more specifically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A class must have a unique responsibility (applies to methods, variables, entities, etc).&lt;/li&gt;
&lt;li&gt;There is a place for everything and everything should be in its place.&lt;/li&gt;
&lt;li&gt;All the variables and methods of the class must be aligned with the objective of the class.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By following these principles, we achieve smaller and simpler classes that have unique objectives. Also we avoid giant classes with generic properties and methods that can be redundant in development.&lt;/p&gt;

&lt;p&gt;Let's see an example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fyawmr5mg00debh2672a6.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fyawmr5mg00debh2672a6.gif" alt="https://media.giphy.com/media/PiQejEf31116URju4V/giphy.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fhoy56b91s923g8pbxj3k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fhoy56b91s923g8pbxj3k.png" alt="https://github.com/elian-ortega/solid-dart/blob/main/assets/single_responsability1.png?raw=true"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's take a look at this &lt;code&gt;signUp ()&lt;/code&gt; function. This could be the method we call from our UI layer to perform the user sign-up process.&lt;/p&gt;

&lt;p&gt;In the code we see that there is functionality of creation, validation, conversion to JSON, and even the call to the database that is normally an API call, so we are clearly not fulfilling the principle.&lt;/p&gt;

&lt;p&gt;This is one of the most common mistakes, especially in Flutter, since developers easily make the mistake of combining different things within the same class or methods.&lt;/p&gt;

&lt;p&gt;⚠️ In other articles and videos we will see how this applies to Clean Architecture ....&lt;/p&gt;

&lt;p&gt;Done, I got it, now ... how do I apply it?&lt;/p&gt;

&lt;p&gt;To follow the &lt;code&gt;Single Responsibility Principle&lt;/code&gt; correctly, we could create methods and classes with simple and unique functionalities.&lt;/p&gt;

&lt;p&gt;In the example method &lt;code&gt;signUp ()&lt;/code&gt; many things are done with different objectives, each of these functionalities could be separated into an individual class with a single objective.&lt;/p&gt;

&lt;h3&gt;
  
  
  The validation
&lt;/h3&gt;

&lt;p&gt;We could implement a class that is responsible for performing the validation, there are many ways to do this, one of them can be to use &lt;code&gt;formz&lt;/code&gt; which is a Flutter package that allows us to create classes for a data type and perform a validation&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Ftdzu4pi4ztoufqia017d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Ftdzu4pi4ztoufqia017d.png" alt="https://github.com/elian-ortega/solid-dart/blob/main/assets/single_responsability2.png?raw=true"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Do not focus too much on the logic of the code, the important thing is to understand that now the validation is decoupled from the rest of the logic with the &lt;code&gt;validator ()&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pub.dev/packages/formz" rel="noopener noreferrer"&gt;Here is the link to formz in pub.dev.&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The connection to the data source
&lt;/h3&gt;

&lt;p&gt;The other error is to call an API from the business logic or UI, this would not fulfill the principle since the connection with the API is a complex functionality by itself, so it would be best to implement a class as &lt;strong&gt;repository&lt;/strong&gt; to which we pass the parameters that we are going to send and delegate the rest of the process to it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F4pp7gqr3aeyiafcq2f12.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F4pp7gqr3aeyiafcq2f12.png" alt="https://github.com/elian-ortega/solid-dart/blob/main/assets/single_responsability3.png?raw=true"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This repository concept is key to meeting the &lt;em&gt;Clean Architecture&lt;/em&gt; standards but we can see that the principle of &lt;strong&gt;Single Responsibility&lt;/strong&gt; is behind this whole idea.&lt;/p&gt;

&lt;p&gt;By implementing these classes applying the principle we would achieve a simpler method compared to how we started with:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fbh8pafi3hp45d378medn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fbh8pafi3hp45d378medn.png" alt="https://github.com/elian-ortega/solid-dart/blob/main/assets/single_responsability4.png?raw=true"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Simpler, more maintainable and &lt;strong&gt;decoupled&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  O: Opened/Closed Principle
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;An entity must be open to extend, but closed to modify.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Este principio nos dice, en resumen, que debemos extender de la entidad para agregar nuevo código en vez de modificar el existente. &lt;/p&gt;

&lt;p&gt;This principles tell us that we must extend our classes to add new code, instead of modifying the existing one.&lt;/p&gt;

&lt;p&gt;The first time we read this it can be a bit confusing but it just is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Don't modify what already works, just extend and add new code.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;n this way, we can develop without damaging the previously tested code. To understand this principle we can see an example provided by &lt;a href="https://www.youtube.com/watch?v=rtmFCcjEgEw&amp;amp;t=735s" rel="noopener noreferrer"&gt;Katerian Trjchevska at LaraconEU 2018&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's imagine that our app has a payment module that currently only accepts debit / credit cards and PayPal as payment methods.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F1x5wes8ywywbjeoi38if.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F1x5wes8ywywbjeoi38if.png" alt="https://github.com/elian-ortega/solid-dart/blob/main/assets/open_closed1.png?raw=true"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At a first glance at the code we may think that everything is fine, but when we analyze its long term &lt;strong&gt;scalability&lt;/strong&gt;, we realize the problem.&lt;/p&gt;

&lt;p&gt;Let's imagine that our client asks us to add a new payment method such as Alipay, gift cards and others.&lt;/p&gt;

&lt;p&gt;Each new payment method implies a new function and a new &lt;code&gt;else if&lt;/code&gt; in the&lt;code&gt;pay ()&lt;/code&gt;method and we could say that this is not a problem, but if we keep adding code within the same class, we would never achieve a stable, ready for production code.&lt;/p&gt;

&lt;p&gt;By applying the &lt;strong&gt;open / closed principle&lt;/strong&gt;, we can create an abstract class &lt;code&gt;PayableInterface&lt;/code&gt; that serves as a payment interface, in this way each of our payment methods extends this abstract class&lt;code&gt;[Payment Method Name] extends PayableInterface&lt;/code&gt; and it can be a separate class that is not affected by modifications made to another.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fj9jnaufwtxo2edv0u1e8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fj9jnaufwtxo2edv0u1e8.png" alt="https://github.com/elian-ortega/solid-dart/blob/main/assets/open_closed2.png?raw=true"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After having our payment logic implemented, we can receive a parameter with the &lt;code&gt;paymentType&lt;/code&gt; that allows us to select the &lt;code&gt;PayableInterface&lt;/code&gt; indicated for the transaction and in this way we do not have to worry about how the&lt;code&gt;pay ()&lt;/code&gt;method makes the payment, only to make a type of filtering so that the correct instance of the interface is used; be it Card, PayPal or Alipay.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F96ypom7lmooqlseg0ldm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F96ypom7lmooqlseg0ldm.png" alt="https://github.com/elian-ortega/solid-dart/blob/main/assets/open_closed3.png?raw=true"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the end we would have a method like this where we can see that the code was reduced to only 3 lines and it is much easier to read.&lt;/p&gt;

&lt;p&gt;It is also more scalable since if we wanted to add a new type of payment method we would only have to extend from &lt;code&gt;PayableInterface&lt;/code&gt; and add it as an option in the filtering method.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;👆 I know these concepts of abstractions and instances are confusing at first but throughout this series of articles and by practice I promise they'll  become simple concepts.&lt;/strong&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  L: Liskov Substitution Principle
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;We can change any concrete instance of a class with any class that implements the same interface.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The main objective of this principle is that we should always obtain the expected behavior of the code regardless of the class instance that is being used.&lt;/p&gt;

&lt;p&gt;To be able to fulfill this principle correctly there are 2 important parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implementation&lt;/li&gt;
&lt;li&gt;Abstraction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first we can see in the previous example of  &lt;strong&gt;Open / Closed Principle&lt;/strong&gt; when we have &lt;code&gt;PayableInterface&lt;/code&gt; and the payment methods that implements it as&lt;code&gt;CardPayment&lt;/code&gt; and &lt;code&gt;PaypalPayment&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the implementation of the code we see that it doesn't matter with implementation we choose, our code should continue to work correctly, this is because both make a correct implementation of the &lt;code&gt;PayableInterface&lt;/code&gt; interface.&lt;/p&gt;

&lt;p&gt;With this example the idea is easy to understand but in practice there are many times that we perform the abstraction process wrong, so we cannot truly make a great use of the principle.&lt;/p&gt;

&lt;p&gt;If you are not very familiar with concepts such as interface, implementation, and abstraction this may sound a bit complex but let's see it with a simple example.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Furf41qp29gc5g8ki51xx.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Furf41qp29gc5g8ki51xx.jpg" alt="https://i.stack.imgur.com/ilxzO.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is one of the iconic images of the principle as it makes it easy to understand.&lt;/p&gt;

&lt;p&gt;Let's imagine that in our code we have a class called &lt;code&gt;DuckInterface&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This gives us the basic functionality of a duck like &lt;code&gt;fly&lt;/code&gt;,&lt;code&gt;swim&lt;/code&gt;, &lt;code&gt;quack&lt;/code&gt; and we would have the&lt;code&gt;RubberDuck&lt;/code&gt; class that implements the interface.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Flzwa82os5c50gdko11w5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Flzwa82os5c50gdko11w5.png" alt="https://github.com/elian-ortega/solid-dart/blob/main/assets/liskov_substitution1.png?raw=true"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At a first glance we could say that our abstraction is fine since we are using an interface that gives us the functionality we need, but the &lt;code&gt;fly ()&lt;/code&gt; method does not apply to a rubber duck,  imagine that our program is going to have different Animals with shared functionality such as flying and swimming, so it would not make sense to leave this method on the &lt;code&gt;DuckInterface&lt;/code&gt; interface.&lt;/p&gt;

&lt;p&gt;To solve this and comply with the &lt;strong&gt;Liskov Principle&lt;/strong&gt; we can create more specific interfaces that allow us to reuse code, which also makes our code more maintainable.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fdeg8ay3vtbktxwh8u7bg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fdeg8ay3vtbktxwh8u7bg.png" alt="https://github.com/elian-ortega/solid-dart/blob/main/assets/liskov_substitution2.png?raw=true"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With this implementation, our &lt;code&gt;RubberDuck&lt;/code&gt; class only implements the methods it needs and now, for example, if we need an animal that fulfills a specific function such as swimming, we could use any class that implements the&lt;code&gt;SwimInterface&lt;/code&gt; interface. This is because by fulfilling the &lt;strong&gt;Liskov Principle&lt;/strong&gt; we can switch any declaration of an &lt;strong&gt;abstract class&lt;/strong&gt; by any class that implements it. &lt;/p&gt;

&lt;h2&gt;
  
  
  I: Interface Segregation Principle
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;The code should not depend on methods that it does not use.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At first this could seem to be the simplest principle but for this very reason, at the beginning, it can even confuse us.&lt;/p&gt;

&lt;p&gt;In the previous principles we have seen the importance of using interfaces to decouple our code.&lt;/p&gt;

&lt;p&gt;This principle ensures that our abstractions for creating interfaces are correct, since we cannot create a new instance of an interface without implementing one of the methods defined by them. The above would be violating the principle&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fvqc8bfn9tza0ak55qf97.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fvqc8bfn9tza0ak55qf97.jpg" alt="https://innovationm.co/wp-content/uploads/2017/11/InterfaceSegregationPrinciple.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This image shows the problem of not fulfilling this principle, we have some instances of classes that do not use all the interface methods, which lead to a dirty code and indicates bad abstraction. &lt;/p&gt;

&lt;p&gt;It is easier to see it with the typical anima example, this is very similar to the example we saw from Liskov.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💡 At this point the examples become similar but the important thing is to see the code from another perspective.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We have an abstract class &lt;code&gt;Animal&lt;/code&gt; that is our interface, it has 3 methods defined  &lt;code&gt;eat ()&lt;/code&gt;,&lt;code&gt;sleep ()&lt;/code&gt;, and&lt;code&gt;fly ()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If we create a &lt;code&gt;Bird&lt;/code&gt; class that implements the animal interface we don't see any problem, but what if we want to create the Dog class?&lt;/p&gt;

&lt;p&gt;Exactly, we realize that we cannot implement the &lt;code&gt;fly ()&lt;/code&gt; method because it does not apply to a dog.&lt;/p&gt;

&lt;p&gt;We could leave it like that and avoid the time needed to restructure the code since we logically know that this would not affect our code, but this breaks the principle.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fbyfr1rbpnpdjf0btehw5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fbyfr1rbpnpdjf0btehw5.png" alt="https://github.com/elian-ortega/solid-dart/blob/main/assets/interface_segregation1.png?raw=true"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The mistake is made by having a bad abstraction in our class and the right thing to do is always refactor to ensure that the principles are being met.&lt;/p&gt;

&lt;p&gt;It may take us a little longer at the moment but the results of having a clean and scalable code should always be priorities.&lt;/p&gt;

&lt;p&gt;A solution to this could be that our &lt;code&gt;Animal&lt;/code&gt; interface only has the methods shared by animals like&lt;code&gt;eat (), sleep ()&lt;/code&gt;and we create another interface for the&lt;code&gt;fly ()&lt;/code&gt;method. In this way, only animals that need this method implement its interface.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fhtvnh4g0f6pxsxainrdt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fhtvnh4g0f6pxsxainrdt.png" alt="https://github.com/elian-ortega/solid-dart/blob/main/assets/interface_segregation2.png?raw=true"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔥 Almost there! Last SOLID principle ...&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  D: Dependency Inversion Principle
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;High-level modules should not depend on low-level modules. Both must depend on abstractions.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In my opinion, this should be the first principle that every developer should understand.&lt;/p&gt;

&lt;p&gt;This principle tells us:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You never have to depend on a concrete implementation of a class, only on its abstractions (interfaces).&lt;/li&gt;
&lt;li&gt;Same as the image presented in &lt;a href="https://dev.to/marcossevilla/cleaner-flutter-vol-1-intro-to-clean-mo6"&gt;Volume 1 of this series of  A Cleaner Flutter&lt;/a&gt; we follow the rule that modules High-level modules should not strictly rely on low-level modules.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To understand it more simply, let's look at the example.&lt;/p&gt;

&lt;p&gt;Nowadays, every app or software that is developed needs to communicate with the outside world. Normally this is done through code repositories that we instantiate and call from the business logic in our software.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Ffvvj1qjabh9kyjhvwwo0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Ffvvj1qjabh9kyjhvwwo0.png" alt="https://github.com/elian-ortega/solid-dart/blob/main/assets/dependency_inversion1.png?raw=true"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Declaring and using a concrete class, such as the &lt;code&gt;DataRepository ()&lt;/code&gt; within &lt;code&gt;BusinessLogic ()&lt;/code&gt;, is a very common practice and is one of the common mistakes that makes our code not very scalable.By depending on a particular instance of a class we surely know it will never be stable because you are constantly adding code to it.&lt;/p&gt;

&lt;p&gt;To solve this problem, the principle tells us to create an interface that communicates both modules. You can even develop a the whole functionality of the business logic and UI of an app by depending on a interface which hasn't been implemented. &lt;/p&gt;

&lt;p&gt;This also allows better communication in a team of developers because when creating an interface, everyone is clear about the objectives of the module and from that definition, it can be verified that the SOLID principles are being met.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fig5wxf1zv2xgf38f3kg0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fig5wxf1zv2xgf38f3kg0.png" alt="https://github.com/elian-ortega/solid-dart/blob/main/assets/dependency_inversion2.png?raw=true"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With this implementation, we create a &lt;code&gt;DataRepositoryInterface&lt;/code&gt; that we can then implement in&lt;code&gt;DataRepository&lt;/code&gt; and the magic happens inside the class that uses this functionality when we do not depend on a concrete instance but instead on an interface  we could pass as parameters any concrete class that implements this interface.&lt;/p&gt;

&lt;p&gt;It could be a local or external database and that would not affect the development since I repeat it again &lt;strong&gt;we do not depend on a single concrete instance, we can use any class that complies with the implementation of the interface.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And this, ladies and gentlemen, is what allows us to fulfill the magic word of &lt;strong&gt;Clean Architecture: &lt;em&gt;Decoupling&lt;/em&gt;!&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap up ...
&lt;/h2&gt;

&lt;p&gt;I remind you that these are principles, not rules, so there is no single way to follow them, their use and compliance with the code will depend on each project, since for many of these the objectives of the project are key to make decisions. Just as something within the scope of a project can be considered small it may under other requirements become something large.&lt;/p&gt;

&lt;p&gt;I hope now you have a better idea of what the &lt;strong&gt;SOLID&lt;/strong&gt; principles are and how to apply them. For any questions or comments you can contact me through my social media accounts and if you learned something do not hesitate to share it with your fellow developers and friends, so that as a community we continue to improve and develop high quality and scalable projects. &lt;/p&gt;

&lt;p&gt;Also, if you liked this content, you can find even more and keep in touch with me on my social networks:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/elian-ortega" rel="noopener noreferrer"&gt;GitHub,&lt;/a&gt; &lt;a href="https://www.linkedin.com/in/elian-ortega/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, &lt;a href="https://twitter.com/ElianOrtegaNCA" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, &lt;a href="https://www.youtube.com/channel/UCPz6bJ3DptMMXu7_hMb1oJQ" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>architecture</category>
      <category>dart</category>
      <category>clean</category>
    </item>
  </channel>
</rss>
