<?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: Tirth Patel</title>
    <description>The latest articles on DEV Community by Tirth Patel (@piedcipher).</description>
    <link>https://dev.to/piedcipher</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%2F115314%2Fbdd00a4c-67bc-48bc-9ef7-ff129f134d8a.jpeg</url>
      <title>DEV Community: Tirth Patel</title>
      <link>https://dev.to/piedcipher</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/piedcipher"/>
    <language>en</language>
    <item>
      <title>Snackbar, Snackbar Everywhere</title>
      <dc:creator>Tirth Patel</dc:creator>
      <pubDate>Wed, 21 Oct 2020 19:33:55 +0000</pubDate>
      <link>https://dev.to/piedcipher/snackbar-snackbar-everywhere-367f</link>
      <guid>https://dev.to/piedcipher/snackbar-snackbar-everywhere-367f</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BKDAd35p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/0%2AErdZ3uKZhxHqfUz6" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BKDAd35p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/0%2AErdZ3uKZhxHqfUz6" alt=""&gt;&lt;/a&gt;Photo by &lt;a href="https://unsplash.com/@shambam?utm_source=medium&amp;amp;utm_medium=referral"&gt;Sam 🐷&lt;/a&gt; on &lt;a href="https://unsplash.com?utm_source=medium&amp;amp;utm_medium=referral"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On Instagram when you bookmark a photo, it shows a snackbar on top of it. Today, we’re going to build a similar experience in Flutter without using any external dependencies &amp;amp; with minimal code!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;So, let’s get started. 🍕&lt;/em&gt;🍫&lt;/p&gt;

&lt;h3&gt;
  
  
  👀 Demo
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QiYHwWb4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AziqE7bjxHExWws4LtMkdxQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QiYHwWb4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AziqE7bjxHExWws4LtMkdxQ.gif" alt=""&gt;&lt;/a&gt;&lt;strong&gt;Demo&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a fresh new flutter project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flutter create snackbar_snackbar_everywhere
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;After that, remove everything from main.dart &amp;amp; paste the following content:&lt;/p&gt;


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



&lt;ul&gt;
&lt;li&gt;In this code, we start off with the MaterialApp &amp;amp; the main Scaffold.&lt;/li&gt;
&lt;li&gt;The main Scaffold’s body contains a ListView.&lt;/li&gt;
&lt;li&gt;Each ListTile consists of a Container whose child is another Scaffold.&lt;/li&gt;
&lt;li&gt;Each of these child scaffold’s have a unique GlobalKey so that a SnackBar can be shown using that key whenever ListTile is tapped 🐍.&lt;/li&gt;
&lt;li&gt;You can play around with the code on &lt;a href="https://dartpad.dev/1ec348937be801ce59b56349e0d214fb"&gt;&lt;strong&gt;this dartpad&lt;/strong&gt;&lt;/a&gt; ** 🎯**.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  That’s it for this one. Thank you for reading this 💙
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;You can find the complete source code in the above gist or dartpad.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;If you find this byte-sized post useful, press👏 button as many times as you can and share this post with others. You can leave your feedback/suggestions in the comments 💬 below.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;For any other issues feel free to reach out to me via Twitter:&lt;/em&gt;&lt;/strong&gt; &lt;a href="https://twitter.com/piedcipher"&gt;https://twitter.com/piedcipher&lt;/a&gt;&lt;/p&gt;




</description>
      <category>dart</category>
      <category>snackbar</category>
      <category>flutter</category>
      <category>instagram</category>
    </item>
    <item>
      <title>Paginate API results with BLoC in Flutter</title>
      <dc:creator>Tirth Patel</dc:creator>
      <pubDate>Wed, 16 Sep 2020 13:02:05 +0000</pubDate>
      <link>https://dev.to/piedcipher/paginate-api-results-with-bloc-in-flutter-3j1o</link>
      <guid>https://dev.to/piedcipher/paginate-api-results-with-bloc-in-flutter-3j1o</guid>
      <description>&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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AczaFDiRDfxMYFNq5" 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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AczaFDiRDfxMYFNq5"&gt;&lt;/a&gt;Photo by &lt;a href="https://unsplash.com/@christinhumephoto?utm_source=medium&amp;amp;utm_medium=referral" rel="noopener noreferrer"&gt;Christin Hume&lt;/a&gt; on &lt;a href="https://unsplash.com?utm_source=medium&amp;amp;utm_medium=referral" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hey Everyone 👋, Today we’re going to learn about Pagination in &lt;a href="https://flutter.dev/" rel="noopener noreferrer"&gt;Flutter&lt;/a&gt;. Pagination is considered as one of the best practices while loading a large chunk of data from an API. Pagination offers better performance and a jank free experience to the user.&lt;/p&gt;

&lt;h3&gt;
  
  
  👀 Demo
&lt;/h3&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%2Fcdn-images-1.medium.com%2Fmax%2F600%2F1%2AMVFw7FPkNIkWnYlNaRh0FA.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%2Fcdn-images-1.medium.com%2Fmax%2F600%2F1%2AMVFw7FPkNIkWnYlNaRh0FA.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🧰 We’ll be using,
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://punkapi.com/documentation/v2" rel="noopener noreferrer"&gt;Punk API&lt;/a&gt; to get some beers 😋.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pub.dev/packages/flutter_bloc" rel="noopener noreferrer"&gt;BLoC&lt;/a&gt; patten for state-management.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pub.dev/packages/json_serializable" rel="noopener noreferrer"&gt;Json Serializable&lt;/a&gt; for automatic serialization-deserialization of the API response.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;So let’s get started 🍻&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🔌 Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Flutter SDK&lt;/li&gt;
&lt;li&gt;IDE of choice: VSCode / Intellij Idea / Android Studio&lt;/li&gt;
&lt;li&gt;Dart &amp;amp; Flutter Plugins for IDE&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🔨 Initial Setup
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;After creating a fresh flutter project, add the following dependencies in pubspec.yaml.&lt;/li&gt;
&lt;/ul&gt;


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


&lt;ul&gt;
&lt;li&gt;Delete everything from the main.dart and paste the following content. It has a main method, app routes, and a bloc observer for debugging purposes. Next, we’ll be building the &lt;strong&gt;DisplayBeerScreen&lt;/strong&gt; widget.&lt;/li&gt;
&lt;/ul&gt;


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


&lt;ul&gt;
&lt;li&gt;I’ve organized the project files feature-wise. Here, we have got only a single feature i.e. display freshly brewed beers.&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%2Fcdn-images-1.medium.com%2Fmax%2F319%2F1%2ANbFvzMiZEVtwZ5N8GcFlnA.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%2Fcdn-images-1.medium.com%2Fmax%2F319%2F1%2ANbFvzMiZEVtwZ5N8GcFlnA.png"&gt;&lt;/a&gt;&lt;strong&gt;Directory Structure&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🎹 Coding
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Let’s design our &lt;strong&gt;BeerRepository.&lt;/strong&gt; It is going to be a singleton. It contains a method &lt;strong&gt;getBeers&lt;/strong&gt; which requires a &lt;strong&gt;page number&lt;/strong&gt;. Page number will be passed from &lt;strong&gt;BeerBloc&lt;/strong&gt;. I have set the &lt;strong&gt;_perPage&lt;/strong&gt; limit to 10.&lt;/li&gt;
&lt;/ul&gt;


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


&lt;ul&gt;
&lt;li&gt;We’ll be creating a model that will map the API response to Dart class (model) using the &lt;strong&gt;fromJson&lt;/strong&gt; method. The model has 5 fields: &lt;strong&gt;id, name, tagline, description,&lt;/strong&gt; and &lt;strong&gt;imageUrl&lt;/strong&gt;. Don’t forget to run flutter pub run build_runner build command to generate the serialization/deserialization code.&lt;/li&gt;
&lt;/ul&gt;


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


&lt;ul&gt;
&lt;li&gt;Now let’s create business logic component related files &amp;amp; classes: &lt;strong&gt;BeerBloc&lt;/strong&gt; , &lt;strong&gt;BeerState&lt;/strong&gt; , and &lt;strong&gt;BeerEvent&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;There will be 4 states: &lt;strong&gt;Initial&lt;/strong&gt; , &lt;strong&gt;Loading&lt;/strong&gt; , &lt;strong&gt;Success&lt;/strong&gt; &amp;amp; &lt;strong&gt;Error&lt;/strong&gt;. These are self-explanatory.&lt;/li&gt;
&lt;/ul&gt;


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


&lt;ul&gt;
&lt;li&gt;There will be 1 event: &lt;strong&gt;BeerFetchEvent&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;


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


&lt;ul&gt;
&lt;li&gt;Now, let’s design &lt;strong&gt;BeerBloc&lt;/strong&gt;. It will handle &lt;strong&gt;BeerFetchEvent&lt;/strong&gt; and yield an appropriate state to the UI. It’ll maintain the current &lt;strong&gt;page&lt;/strong&gt; number and &lt;strong&gt;isFetching&lt;/strong&gt; boolean flag to prevent duplicate event requests. &lt;strong&gt;BeerRepository&lt;/strong&gt; is injected via &lt;strong&gt;BeerBloc&lt;/strong&gt; constructor. The value of the &lt;strong&gt;page&lt;/strong&gt; is incremented by 1 after the Success state is yielded.&lt;/li&gt;
&lt;li&gt;We’ll be yielding &lt;strong&gt;BeerInitialState&lt;/strong&gt; as the Initial State of the UI.&lt;/li&gt;
&lt;li&gt;When &lt;strong&gt;BeerFetchEvent&lt;/strong&gt; is delegated to the &lt;strong&gt;BeerBloc&lt;/strong&gt; , first it’ll yield the &lt;strong&gt;BeerLoadingState&lt;/strong&gt;. Then, it’ll call the &lt;strong&gt;getBeers&lt;/strong&gt; method of &lt;strong&gt;BeerRepository.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;If the return type of &lt;strong&gt;response&lt;/strong&gt; is of type &lt;strong&gt;http.Response&lt;/strong&gt; then status code of the response is checked. If it’s &lt;strong&gt;OK&lt;/strong&gt; , then we’ll parse the JSON using &lt;strong&gt;jsonDecode&lt;/strong&gt; from &lt;strong&gt;dart:convert&lt;/strong&gt; , and map individual objects to &lt;strong&gt;BeerModel&lt;/strong&gt;. Now, these results can be passed to UI by yielding &lt;strong&gt;BeerSuccessState&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Otherwise, &lt;strong&gt;BeerErrorState&lt;/strong&gt; is yielded to UI to notify about errors that occurred during API call.&lt;/li&gt;
&lt;/ul&gt;


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


&lt;ul&gt;
&lt;li&gt;At last, comes the UI building part. I’ve kept it clean and simple. There are 3 widgets that compose the entire UI: &lt;strong&gt;DisplayBeerScreen, BeerBody,&lt;/strong&gt; and &lt;strong&gt;BeerListItem&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DisplayBeerScreen&lt;/strong&gt; widget displays an &lt;strong&gt;AppBar&lt;/strong&gt; , injects &lt;strong&gt;BeerBloc&lt;/strong&gt; instance via &lt;strong&gt;BlocProvider&lt;/strong&gt; , and renders &lt;strong&gt;BeerBody&lt;/strong&gt;  widget.&lt;/li&gt;
&lt;/ul&gt;


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


&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;BeerBody&lt;/strong&gt; widget returns a &lt;strong&gt;BlocConsumer&lt;/strong&gt; to build the reactive UI. &lt;strong&gt;BeerBody&lt;/strong&gt; has 2 fields: a list to hold &lt;strong&gt;BeerModel&lt;/strong&gt; s (_beers), and a &lt;strong&gt;ScrollController&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;listener&lt;/strong&gt; callback of &lt;strong&gt;BlocConsumer&lt;/strong&gt; conditionally displays the appropriate message using a SnackBar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;builder&lt;/strong&gt; callback of &lt;strong&gt;BlocConsumer&lt;/strong&gt; conditionally builds the widgets. Let’s understand that logic:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Case (1):&lt;/strong&gt; If the current state is either &lt;strong&gt;initial&lt;/strong&gt; or &lt;strong&gt;loading&lt;/strong&gt; and the value of &lt;strong&gt;_beers&lt;/strong&gt; is empty. In this case, a progress bar is shown. This condition only occurs when the user opens the app for the first time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Case (2):&lt;/strong&gt; If the current state is an &lt;strong&gt;error&lt;/strong&gt; and the value of &lt;strong&gt;_beers&lt;/strong&gt; is empty. In this case, &lt;strong&gt;IconButton&lt;/strong&gt; with retry action is shown. This condition only occurs when the user opens the app for the first time and there is some error due to the internet or any other exception. If the user presses the retry then the value of &lt;strong&gt;isFetching&lt;/strong&gt; field of &lt;strong&gt;BeerBloc&lt;/strong&gt; is set to  &lt;strong&gt;false&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Case (3):&lt;/strong&gt; If the current state is a success. In this case, beers (API response) yielded by the BLoC are added to the &lt;strong&gt;_beers&lt;/strong&gt; list &amp;amp; &lt;strong&gt;isFetching&lt;/strong&gt; field of &lt;strong&gt;BeerBloc&lt;/strong&gt; is set to  &lt;strong&gt;false&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;By default, the &lt;strong&gt;builder&lt;/strong&gt; returns a &lt;strong&gt;ListView&lt;/strong&gt; to render the &lt;strong&gt;_beers&lt;/strong&gt; using the &lt;strong&gt;BeerListItem&lt;/strong&gt; widget. &lt;strong&gt;ListView&lt;/strong&gt; ’s controller is set to a &lt;strong&gt;ScrollController&lt;/strong&gt; instance. This controller has a listener which adds a &lt;strong&gt;BeerFetchEvent&lt;/strong&gt; to &lt;strong&gt;BeerBloc (&lt;/strong&gt;to get the response from the next page of the API) if the user has reached the end of the list-view. It also sets &lt;strong&gt;isFetching&lt;/strong&gt; field of &lt;strong&gt;BeerBloc&lt;/strong&gt; is set to &lt;strong&gt;true&lt;/strong&gt; to prevent duplicate event requests.&lt;/li&gt;
&lt;/ul&gt;


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


&lt;ul&gt;
&lt;li&gt;Finally, there is the &lt;strong&gt;BeetListItem&lt;/strong&gt; widget which shows individual &lt;strong&gt;BeerModel&lt;/strong&gt; data using &lt;strong&gt;ExpansionTile&lt;/strong&gt; , &lt;strong&gt;Text&lt;/strong&gt; , &lt;strong&gt;Image.network,&lt;/strong&gt; and some &lt;strong&gt;SizedBox&lt;/strong&gt; es.&lt;/li&gt;
&lt;/ul&gt;


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


&lt;h3&gt;
  
  
  That’s it for this one. Thank you for reading this 💙
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;You can find the complete source code of this app in this repository.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/piedcipher/beer-app" rel="noopener noreferrer"&gt;piedcipher/beer-app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;If you find this post useful, press👏 button as many times as you can and share this post with others. You can leave your feedback/suggestions in the comments 💬 below.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;For any other issues feel free to reach out to me via Twitter:&lt;/em&gt;&lt;/strong&gt; &lt;a href="https://twitter.com/piedcipher" rel="noopener noreferrer"&gt;https://twitter.com/piedcipher&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dart</category>
      <category>flutter</category>
      <category>httprequest</category>
      <category>bloc</category>
    </item>
  </channel>
</rss>
