<?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: Albert</title>
    <description>The latest articles on DEV Community by Albert (@txe_bert).</description>
    <link>https://dev.to/txe_bert</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%2F178856%2F6d078dc3-47e0-402e-9499-4e8be80c8aa8.jpg</url>
      <title>DEV Community: Albert</title>
      <link>https://dev.to/txe_bert</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/txe_bert"/>
    <language>en</language>
    <item>
      <title>Async Programming in Flutter with streams</title>
      <dc:creator>Albert</dc:creator>
      <pubDate>Fri, 17 Jul 2020 09:58:11 +0000</pubDate>
      <link>https://dev.to/txe_bert/async-programming-in-flutter-with-streams-58dp</link>
      <guid>https://dev.to/txe_bert/async-programming-in-flutter-with-streams-58dp</guid>
      <description>&lt;p&gt;Asynchronous Programming is a principle that allows a portion of your programs run while waiting for some other activities to occur in your application thread. It allows portions of your code run independently from the main workflow.&lt;/p&gt;

&lt;p&gt;A couple of examples of asynchronous processes are: fetching data from network, or looping over some very large chunk of data.&lt;/p&gt;

&lt;p&gt;In flutter there are a series of ways to write asynchronous code. Some popular methods are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Future.&lt;/li&gt;
&lt;li&gt;Async/Await.&lt;/li&gt;
&lt;li&gt;Streams.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The purpose of this article is to get you started using streams in your flutter apps, and I expect you to have prior knowledge about writing flutter apps, let’s get to it!&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Reactive Programming?
&lt;/h3&gt;

&lt;p&gt;According to  &lt;a href="https://en.wikipedia.org/wiki/Reactive_programming"&gt;Wikipedia&lt;/a&gt; :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Reactive programming is a programming paradigm oriented around data flows and the propagation of change. This means that it should be possible to express static or dynamic data flows with ease in the programming languages used, and that the underlying execution model will automatically propagate changes through the data flow.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In reactive programming, data flows in a structure set by the language, framework, or library you use in such a way that when data is passed into the structure on one end, the output will always update itself if the value of that data changes.&lt;/p&gt;

&lt;p&gt;This is exactly what streams do. A stream is a flow of asynchronous events, View it as a pipe containing a liquid. You pour in the liquid from one end of the pipe and it comes out the other end.&lt;/p&gt;

&lt;p&gt;Streams can carry and process different types of data, like an object, a function, a map, a list, even streams of streams. Pretty cool eh?&lt;/p&gt;

&lt;h3&gt;
  
  
  Now, Code Examples
&lt;/h3&gt;

&lt;p&gt;The first example creates a simple stream that takes in a string and prints it out when done:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="nd"&gt;@override&lt;/span&gt;
 &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;initState&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;initState&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;Stream&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromFuture&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputData&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
  &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
     &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Our data: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
 &lt;span class="o"&gt;},&lt;/span&gt; &lt;span class="nl"&gt;onDone:&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
     &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Done"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;},&lt;/span&gt; &lt;span class="nl"&gt;onError:&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error returned"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
   &lt;span class="o"&gt;});&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;inputData&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="n"&gt;async&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
     &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Fetching Data..."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Let's Use Streams!"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



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

&lt;blockquote&gt;
&lt;p&gt;Fetching data...&lt;/p&gt;

&lt;p&gt;Our Data: Let’s use Streams!&lt;/p&gt;

&lt;p&gt;Done&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here, The Stream gets its data from the &lt;code&gt;inputData()&lt;/code&gt; function which returns the text &lt;em&gt;“Let’s use streams!”&lt;/em&gt;. Then we use &lt;code&gt;stream.listen()&lt;/code&gt; to work on the data entering the stream. In here we have an &lt;code&gt;onDone()&lt;/code&gt;, and &lt;code&gt;onError()&lt;/code&gt; method. &lt;code&gt;onDone()&lt;/code&gt; uses the data when the process is completed, and &lt;code&gt;onError()&lt;/code&gt; can be used to throw an error if there is one.&lt;/p&gt;

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



&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;StreamController&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StreamController&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
 &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"received data: &lt;/span&gt;&lt;span class="si"&gt;$data&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;},&lt;/span&gt; &lt;span class="nl"&gt;onDone:&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Stream done"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;},&lt;/span&gt; &lt;span class="nl"&gt;onError:&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error occured"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;});&lt;/span&gt;
&lt;span class="c1"&gt;// data flowing into the stream&lt;/span&gt;
   &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sink&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'stream controllers are awesome'&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
   &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sink&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Because You can do more"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
   &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sink&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'random string'&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Close the StreamController when done to avoid memory leaks&lt;/span&gt;
   &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



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

&lt;blockquote&gt;
&lt;p&gt;received data: stream controllers are awesome&lt;/p&gt;

&lt;p&gt;received data: Because you can do more&lt;/p&gt;

&lt;p&gt;received data: random string&lt;/p&gt;

&lt;p&gt;Stream done&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The &lt;code&gt;StreamController&lt;/code&gt; class creates a controller for any stream that is created. making it easier for you to use multiple listeners(we’ll get to that soon). Here we’re adding our data using &lt;code&gt;sink.add()&lt;/code&gt;, which is an object that accepts data being entered into the stream. Also, you should close your controller after using it, to prevent &lt;em&gt;memory leaks&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Broadcast Streams
&lt;/h3&gt;

&lt;p&gt;This type of stream allows you to use multiple numbers of listeners. The streams we created before could only have one listener; they’re known as single-subscription streams.&lt;/p&gt;

&lt;h3&gt;
  
  
  Code example
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;initState&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
 &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;initState&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
 &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;//add a .broadcast() &lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;StreamController&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StreamController&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;broadcast&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; 
  &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;)).&lt;/span&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
 &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DataReceived: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;},&lt;/span&gt; &lt;span class="nl"&gt;onDone:&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Task 1 Done"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;},&lt;/span&gt; &lt;span class="nl"&gt;onError:&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Some Error"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;});&lt;/span&gt;
  &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;)).&lt;/span&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
 &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DataReceived: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="o"&gt;},&lt;/span&gt; &lt;span class="nl"&gt;onDone:&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Task 2 Done"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;});&lt;/span&gt;
   &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;)).&lt;/span&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;},&lt;/span&gt; &lt;span class="nl"&gt;onDone:&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Task 3 Done"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;});&lt;/span&gt;
   &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sink&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'random string'&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
   &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sink&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1234&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
   &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sink&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;({&lt;/span&gt;&lt;span class="s"&gt;'key 1'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'value A'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'key 2'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'value B'&lt;/span&gt;&lt;span class="o"&gt;});&lt;/span&gt;
   &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



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

&lt;blockquote&gt;
&lt;p&gt;DataReceived: random string&lt;/p&gt;

&lt;p&gt;DataReceived: 1234&lt;/p&gt;

&lt;p&gt;{key 1: value A, key 2: value B}&lt;/p&gt;

&lt;p&gt;Task 1 Done&lt;/p&gt;

&lt;p&gt;Task 2 Done&lt;/p&gt;

&lt;p&gt;Task 3 Done&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here, we initialize a &lt;code&gt;StreamController&lt;/code&gt; with &lt;code&gt;.broadcast()&lt;/code&gt; then, we listen to the stream three different times. Notice we used a &lt;code&gt;.where()&lt;/code&gt; method before listening, this helps me to only listen to data in the stream that meets a given condition. First, we only print strings, then integers, then maps.&lt;/p&gt;

&lt;p&gt;That's all for this post, now you know how to create and use a stream 🎉. &lt;/p&gt;

&lt;p&gt;Need help with something? you can find me on &lt;a href="https://twitter.com/txe_bert"&gt;twitter&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>dart</category>
      <category>streams</category>
      <category>async</category>
    </item>
    <item>
      <title>Storing local data with hive (and provider) in flutter</title>
      <dc:creator>Albert</dc:creator>
      <pubDate>Fri, 17 Jul 2020 00:21:07 +0000</pubDate>
      <link>https://dev.to/txe_bert/storing-local-data-with-hive-and-provider-in-flutter-5def</link>
      <guid>https://dev.to/txe_bert/storing-local-data-with-hive-and-provider-in-flutter-5def</guid>
      <description>&lt;p&gt;One of the most important parts of app development is data storage and manipulation, and the same is true for flutter apps. There are many ways to store local data in flutter apps, but in this article, &lt;em&gt;we will learn about just one&lt;/em&gt; - &lt;strong&gt;&lt;em&gt;hive&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Hive is a fast, lightweight, NoSQL database, for &lt;strong&gt;flutter&lt;/strong&gt; and &lt;strong&gt;dart&lt;/strong&gt; apps. Hive is really useful if you want a simple key-value database, without many relations, and really easy to use.&lt;/p&gt;

&lt;p&gt;In this article, we'll go over these steps to build a simple CRUD app with hive:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setup Project&lt;/li&gt;
&lt;li&gt;Setup hive&lt;/li&gt;
&lt;li&gt;Type Adapters&lt;/li&gt;
&lt;li&gt;Storing data&lt;/li&gt;
&lt;li&gt;Reading data&lt;/li&gt;
&lt;li&gt;Update and Delete data&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;I won't be talking much about provider setup or UIs in this article, so you should already have some idea about adding provider to your project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup Project
&lt;/h2&gt;

&lt;p&gt;To do the CRUD operations we'll be using a simple inventory app, where you can create inventory items, update and delete them when you want to. For ease,  I've set up the project and put it on &lt;a href="https://github.com/a-oboh/flutter-hive-example"&gt;Github&lt;/a&gt; in the &lt;strong&gt;starter&lt;/strong&gt; folder, it contains the UI and the provider setup.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/a-oboh"&gt;
        a-oboh
      &lt;/a&gt; / &lt;a href="https://github.com/a-oboh/flutter-hive-example"&gt;
        flutter-hive-example
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;you can clone it and follow from there.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3FQRSgk_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1594748113066/e4_BuwC9v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3FQRSgk_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1594748113066/e4_BuwC9v.png" alt="hive_starter"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Add Dependencies
&lt;/h3&gt;

&lt;p&gt;After creating your project (or cloning mine), as usual, you need to add some dependencies in order to continue building the app. the dependencies we'll be adding are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pub.dev/packages/hive"&gt;Hive&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pub.dev/packages/provider"&gt;Provider&lt;/a&gt; - for state management&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pub.dev/packages/path_provider"&gt;Path Provider&lt;/a&gt; - to get the device directory
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;hive&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^1.4.1+1&lt;/span&gt;
&lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^4.3.1&lt;/span&gt;
&lt;span class="na"&gt;path_provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^1.6.5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;we also need to add  &lt;a href="https://pub.dev/packages/hive_generator"&gt;hive_generator&lt;/a&gt; and &lt;a href="https://pub.dev/packages/build_runner"&gt;build_runner&lt;/a&gt; to the dev dependencies:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;hive_generator&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^0.5.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Hive generator helps us generate type adapters, you'll see why later on in the article.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;along with the other dependencies already in the starter project.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Setup Hive
&lt;/h2&gt;

&lt;p&gt;Before you can use the hive, you need to initialize it. This is done in the &lt;code&gt;main()&lt;/code&gt; function of your app before &lt;code&gt;runApp()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:hive/hive.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:path_provider/path_provider.dart'&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pathProvider&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="n"&gt;async&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Directory&lt;/span&gt; &lt;span class="n"&gt;directory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="n"&gt;pathProvider&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getApplicationDocumentsDirectory&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;Hive&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;init&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;runApp&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;First, import &lt;code&gt;path_provider&lt;/code&gt;, because Hive needs a home directory as it is initialized.&lt;/li&gt;
&lt;li&gt;Next, get the directory from the &lt;code&gt;path_provider&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Finally, initialize hive with the path of the directory.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Hive Boxes
&lt;/h3&gt;

&lt;p&gt;Hive stores its data in &lt;code&gt;boxes&lt;/code&gt;, containing key-value pairs. I like to see boxes as a folder with files listed and sorted by a numbering system, or as normal maps in dart. With hive, before you can read/write data a box must be opened. boxes can be opened with &lt;code&gt;await Hive.openBox('name')&lt;/code&gt;, and you can get an instance of an opened box with &lt;code&gt;Hive.box('name')&lt;/code&gt;, where 'name' is the name of the box (kind of saying the DB name).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;you can call &lt;code&gt;Hive.openBox('name')&lt;/code&gt; even if you already have the box opened somewhere else, sometimes it may be smart to do this.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Type Adapters
&lt;/h3&gt;

&lt;p&gt;Hive allows you to store most standard types - String, int, Map, List, DateTime, but most times you want to have a model class for your data because this makes development much easier and faster. In order to use these model types, you need to register  &lt;a href="https://pub.dev/documentation/hive/latest/hive/TypeAdapter-class.html"&gt;TypeAdapters&lt;/a&gt; which helps you encode/decode your object to binary form on disk. You can write your Type Adapters manually, but we'll just be generating ours with the &lt;code&gt;hive_generator&lt;/code&gt; and &lt;code&gt;build_runner&lt;/code&gt; packages we added to our dev dependencies earlier.&lt;/p&gt;

&lt;p&gt;Somewhere in your &lt;code&gt;lib/&lt;/code&gt; folder, you can create your model file (mine is called &lt;code&gt;inventory_model.dart&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Now let's create the class and add the right annotations so the TypeAdapters can be generated:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:hive/hive.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;'inventory_model.g.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@HiveType&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;Inventory&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@HiveField&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&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="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@HiveField&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&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="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;Inventory&lt;/span&gt;&lt;span class="o"&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;name&lt;/span&gt;&lt;span class="o"&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;description&lt;/span&gt;&lt;span class="o"&gt;});&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;First import hive&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;'inventory_model.g.dart'&lt;/code&gt; as a part (this is where the typeadapter is generated)&lt;/li&gt;
&lt;li&gt;Annotate the model class with &lt;code&gt;@HiveType()&lt;/code&gt;, so the generator knows this should be a TypeAdapter.&lt;/li&gt;
&lt;li&gt;Annotate each field you want to save with &lt;code&gt;@HiveField(index)&lt;/code&gt;, the index is an int and each index should appear once and you shouldn't change it after registering them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Run the generator by typing the following command in the terminal:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ flutter packages pub run build_runner build
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;After generating the type adapters, you may get an error about some missing implementations: &lt;code&gt;Missing concrete implementation of 'getter TypeAdapter.typeId'&lt;/code&gt;. you can fix this by overriding the getter - typeId and returning an integer (also unique like HiveField) I use 0 in my case because this is my first type adapter.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="nd"&gt;@override&lt;/span&gt;
 &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;typeId&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Finally, register the type adapter in your main function, just add it beneath your hive initialization.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;Hive&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;registerAdapter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;InventoryAdapter&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="n"&gt;runApp&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Storing Data
&lt;/h3&gt;

&lt;p&gt;To store data we'll create a method in our ChangeNotifier class:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;addItem&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Inventory&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;async&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Hive&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;openBox&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Inventory&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;'inventory'&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;box&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;notifyListeners&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Here, we open the box and then use the &lt;code&gt;add()&lt;/code&gt; method to append the data to our box. you can also use the &lt;code&gt;put()&lt;/code&gt; method, the difference is with &lt;code&gt;put()&lt;/code&gt; you have to specify the key for each value - &lt;code&gt;box.put('key', item)&lt;/code&gt;, but &lt;code&gt;add()&lt;/code&gt; just gives each value an index and auto increments it. There's also &lt;code&gt;box.putAll({'key': value})&lt;/code&gt; which takes in a map, and &lt;code&gt;box.addAll( )&lt;/code&gt; which takes in a list, they are useful for adding multiple values at once.&lt;/p&gt;

&lt;p&gt;To use this in the UI:&lt;/p&gt;


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



&lt;p&gt;&lt;em&gt;just replace the RaisedButton to that in the gist above.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Reading data
&lt;/h3&gt;

&lt;p&gt;There are different ways to read data from your boxes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;box.get('key)&lt;/code&gt; - get the value from a key.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;box.getAt(index)&lt;/code&gt; - get the value from an index created with &lt;code&gt;box.add()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;box.values&lt;/code&gt; - this returns an iterable containing all the items in the box.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;get the values by adding this to the change notifier class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;List&lt;/span&gt; &lt;span class="n"&gt;_inventoryList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Inventory&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;[];&lt;/span&gt;
&lt;span class="n"&gt;List&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;inventoryList&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_inventoryList&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;getItem&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="n"&gt;async&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Hive&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;openBox&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Inventory&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;'inventory'&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;_inventoryList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;box&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;notifyListeners&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;You should probably understand the code by now.&lt;/p&gt;

&lt;p&gt;Add this to the top of the &lt;code&gt;build()&lt;/code&gt; method:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;watch&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;HomeModel&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="na"&gt;getItem&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Replace the &lt;code&gt;ListView.builder()&lt;/code&gt; in the UI with:&lt;/p&gt;


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



&lt;h3&gt;
  
  
  Updating Items
&lt;/h3&gt;

&lt;p&gt;To update, there's a popup menu button on each item card.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ciZS8Gip--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1594926881790/42KQdFtSM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ciZS8Gip--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1594926881790/42KQdFtSM.png" alt="pop_up_menu_button.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To update you can use &lt;code&gt;box.put('key', newValue)&lt;/code&gt; to update that value, or &lt;code&gt;box.putAt(index, item)&lt;/code&gt; which works like &lt;code&gt;getAt()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In our change notifier class we add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;updateItem&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Inventory&lt;/span&gt; &lt;span class="n"&gt;inventory&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Hive&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;box&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Inventory&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;'inventory'&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;box&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;putAt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;inventory&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;notifyListeners&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Delete Items
&lt;/h3&gt;

&lt;p&gt;Deleting items is similar to getting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;box.delete('key)&lt;/code&gt; - get the value from a key.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;box.deleteAt(index)&lt;/code&gt; - get the value from an index created with &lt;code&gt;box.add()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;box.deleteAll(keys)&lt;/code&gt; - accepts an iterable of keys, and deletes all the keys given.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;There's also a &lt;code&gt;deleteFromDisk()&lt;/code&gt; method - this deletes the file where the box was created on the device&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;deleteItem&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Hive&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;box&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Inventory&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;_inventoryBox&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;box&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;deleteAt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;getInventory&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;notifyListeners&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Lazy Boxes
&lt;/h3&gt;

&lt;p&gt;Lazy Boxes - Lazy boxes are useful for large apps or boxes with a lot of data because they don't load all the data from disk at once. to use a lazy box:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;lazyBox&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Hive&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;openLazyBox&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'name'&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="n"&gt;lazyBox&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'key'&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;em&gt;note the &lt;code&gt;await&lt;/code&gt; keyword on get().&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Remember, though Hive is really cool and useful, I feel you should use it if there are few or no relations in your data. That's all for this article, I hope it helps! Need help with something? You can reach me on twitter  &lt;a href="https://twitter.com/txe_bert"&gt;@txe_bert&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>dart</category>
      <category>database</category>
      <category>android</category>
    </item>
  </channel>
</rss>
