<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
        <title>Dart - Tag - Notes about stuff</title>
        <link>/tags/dart/</link>
        <description>Dart - Tag - Notes about stuff</description>
        <generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Fri, 20 Jan 2023 22:19:36 &#43;0100</lastBuildDate><atom:link href="/tags/dart/" rel="self" type="application/rss+xml" /><item>
    <title>Futures, async, await in Dart</title>
    <link>/posts/2023-01-20_async/</link>
    <pubDate>Fri, 20 Jan 2023 22:19:36 &#43;0100</pubDate>
    <author>Kamila Chyla</author>
    <guid>/posts/2023-01-20_async/</guid>
    <description><![CDATA[<div class="featured-image">
                <img src="/dart.png" referrerpolicy="no-referrer">
            </div><p>Notes about asynchronous programing in Dart. In this article I test and learn about two variants of writing asynchronous code in Dart: async/await and Future-based.</p>
<h1 id="goal">Goal</h1>
<p>As I learn Dart, I want to reinforce - or rather feel - how asynchronous programming look like. I already have some basic experience with JavaScript and I think Dart Futures are similar.</p>
<p>My goal in this article is to go through a very simple Dart code examples and learn about Futures, making the code a bit more complex bit by bit. I thought it would be funny to try and compare two ways (or flavours) of writing asynchronous code.</p>
<h1 id="create-a-future">Create a future</h1>
<p>Let&rsquo;s create a simple <code>compute</code> function that mimics heavy calculation. After two secons returned future would be completed with value 1.</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-dart">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="cl"><span class="n">Future</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">compute</span><span class="p">({</span><span class="kt">bool</span> <span class="nl">throwing:</span> <span class="kc">false</span><span class="p">})</span> <span class="kd">async</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="p">(</span><span class="n">throwing</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">throw</span> <span class="n">MyError</span><span class="p">(</span><span class="nl">message:</span> <span class="s1">&#39;calculation exception&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">Future</span><span class="p">.</span><span class="n">delayed</span><span class="p">(</span><span class="n">Duration</span><span class="p">(</span><span class="nl">seconds:</span> <span class="m">2</span><span class="p">),</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="m">1</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>
<p>Single optional parameter (<code>false</code> by default) allows to force the function into throwing an exception <code>MyError</code>. Here is the definition of <code>MyError:</code></p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-dart">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="cl"><span class="kd">class</span> <span class="nc">MyError</span> <span class="kd">implements</span> <span class="n">Exception</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kd">final</span> <span class="kt">String</span> <span class="n">message</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="kd">final</span> <span class="n">Exception</span><span class="o">?</span> <span class="n">cause</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="n">MyError</span><span class="p">({</span><span class="k">this</span><span class="p">.</span><span class="n">message</span> <span class="o">=</span> <span class="s2">&#34;Default error&#34;</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="n">cause</span> <span class="o">=</span> <span class="kc">null</span><span class="p">});</span>
</span></span><span class="line"><span class="cl">  <span class="kt">String</span> <span class="n">toString</span><span class="p">()</span> <span class="o">=&gt;</span> <span class="s2">&#34;MyError: </span><span class="si">${</span><span class="n">message</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>
<p>The <code>throwing</code> parameter would let me test the behavior of the returned future later. I can call <code>compute(..)</code> in two ways: forcing it to throw or not to force:</p>
<h2 id="complete-future-with-value">Complete future with value</h2>
<p>Letthe future complete with value. <code>main</code> would call <code>compute()</code> and print the result:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-dart">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="cl"><span class="kt">void</span> <span class="n">main</span><span class="p">(</span><span class="n">List</span><span class="o">&lt;</span><span class="kt">String</span><span class="o">&gt;</span> <span class="n">args</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">compute</span><span class="p">().</span><span class="n">then</span><span class="p">((</span><span class="n">v</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">print</span><span class="p">(</span><span class="n">v</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>
<p>or</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-dart">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="cl"><span class="kt">void</span> <span class="n">main</span><span class="p">(</span><span class="n">List</span><span class="o">&lt;</span><span class="kt">String</span><span class="o">&gt;</span> <span class="n">args</span><span class="p">)</span> <span class="kd">async</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">print</span><span class="p">(</span><span class="kd">await</span> <span class="n">compute</span><span class="p">());</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>
<p>Both variants do the same (print &ldquo;1&rdquo; after 2 seconds).</p>
<p>I present here both code styles which can be used to express asynchrony in Dart code. Both exist e.g. in JavaScript. If you were ever writing  asynchronous code in JS then Dart will feel like home.</p>
<ul>
<li>first style is &ldquo;callback&rdquo; style  in which resulting Future allows to call its method like: <code>then</code>, <code>onError</code>, <code>timeout</code> or <code>catchError</code>. Those methods take other functions that can handle different scenarios of possible future completion (by error or by value).</li>
<li>second style is called &ldquo;async/await&rdquo;; function that is using <code>await</code> must be declared as being <code>async</code> in method signature.</li>
</ul>
<h2 id="complete-future-with-exception">Complete future with exception</h2>
<p><code>main</code> would call <code>compute({throwing: true})</code> and print result like this:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-dart">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="cl"><span class="kt">void</span> <span class="n">main</span><span class="p">(</span><span class="n">List</span><span class="o">&lt;</span><span class="kt">String</span><span class="o">&gt;</span> <span class="n">args</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">compute</span><span class="p">(</span><span class="nl">throwing:</span> <span class="kc">true</span><span class="p">).</span><span class="n">then</span><span class="p">((</span><span class="n">v</span><span class="p">){</span>
</span></span><span class="line"><span class="cl">    <span class="n">print</span><span class="p">(</span><span class="n">v</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>
<p>or like this:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-dart">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="cl"><span class="kt">void</span> <span class="n">main</span><span class="p">(</span><span class="n">List</span><span class="o">&lt;</span><span class="kt">String</span><span class="o">&gt;</span> <span class="n">args</span><span class="p">)</span> <span class="kd">async</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">print</span><span class="p">(</span><span class="kd">await</span> <span class="n">compute</span><span class="p">(</span><span class="nl">throwing:</span> <span class="kc">true</span><span class="p">));</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>
<p>Both variants produce:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-bash">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">Unhandled exception:
</span></span><span class="line"><span class="cl">My error: calculation exception
</span></span><span class="line"><span class="cl"><span class="c1">#0      compute (file:///home/karma/dev/dart/asyncerr/main.dart:3:5)</span>
</span></span><span class="line"><span class="cl"><span class="c1">#1      main (file:///home/karma/dev/dart/asyncerr/main.dart:36:15)</span>
</span></span><span class="line"><span class="cl"><span class="c1">#2      _delayEntrypointInvocation.&lt;anonymous closure&gt; (dart:isolate-patch/isolate_patch.dart:295:32)</span>
</span></span><span class="line"><span class="cl"><span class="c1">#3      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:192:12)</span></span></span></code></pre></div></div>
<p>Now, based on the two ways of calling asynchronous code, let&rsquo;s see what we can do with exceptional situations.</p>
<h1 id="exceptions">Exceptions</h1>
<p>Let&rsquo;s assume our computation throws exception. What can we do about it? Let&rsquo;s handle it by printing the exception to stdout. This behavior of handling an error would be implemented in a separate function and would simply print the exception:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-dart">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="cl"><span class="kt">void</span> <span class="n">_handleError</span><span class="p">(</span><span class="n">Exception</span> <span class="n">e</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">print</span><span class="p">(</span><span class="s2">&#34;_handleError: </span><span class="si">$</span><span class="n">e</span><span class="s2">&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>
<p>I can use it in try-on-catch block in async main:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-dart">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="cl"><span class="kt">void</span> <span class="n">main</span><span class="p">(</span><span class="n">List</span><span class="o">&lt;</span><span class="kt">String</span><span class="o">&gt;</span> <span class="n">args</span><span class="p">)</span> <span class="kd">async</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">a</span> <span class="o">=</span> <span class="kd">await</span> <span class="n">compute</span><span class="p">(</span><span class="nl">throwing:</span> <span class="kc">true</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">print</span><span class="p">(</span><span class="n">a</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span> <span class="n">on</span> <span class="n">Exception</span> <span class="k">catch</span> <span class="p">(</span><span class="n">e</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">_handleError</span><span class="p">(</span><span class="n">e</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>
<p>which will result in:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-zsh">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zsh" data-lang="zsh"><span class="line"><span class="cl">_handleError: My error: calculation exception</span></span></code></pre></div></div>
<p>Note: this code will only catch subclasses of Exception. To handle other types, you need to catch other possible things that are thrown (everything can be thrown: integers, arbitrary objects&hellip;.) (<a href="https://stackoverflow.com/questions/56803689/flutter-and-dart-try-catch-catch-does-not-fire" target="_blank" rel="noopener noreffer ">credits: SO</a>):</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-dart">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="cl"><span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="p">...</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span> <span class="n">on</span> <span class="n">Exception</span> <span class="k">catch</span> <span class="p">(</span><span class="n">exception</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="p">...</span> <span class="c1">// only executed if error is of type Exception
</span></span></span><span class="line"><span class="cl"><span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">error</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="p">...</span> <span class="c1">// executed for errors of all types other than Exception
</span></span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>
<p>Other variant of the code, using Future&rsquo;s onError, requires some special attention, because this code simply does not compile:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-dart">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="cl"><span class="kt">void</span> <span class="n">main</span><span class="p">(</span><span class="n">List</span><span class="o">&lt;</span><span class="kt">String</span><span class="o">&gt;</span> <span class="n">args</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">compute</span><span class="p">(</span><span class="nl">throwing:</span> <span class="kc">true</span><span class="p">).</span><span class="n">onError</span><span class="p">(</span><span class="n">_handleError</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>
<blockquote>
<p>The argument type &lsquo;void Function(Exception)&rsquo; can&rsquo;t be assigned to the parameter type &lsquo;FutureOr<int> Function(Object, StackTrace)&rsquo;.dartargument_type_not_assignable</p>
</blockquote>
<p>so I need to:</p>
<ol>
<li>write a test that would filter out thrown values and only trigger handler if the test passes (here I test that thrown value is of type MyError) and</li>
<li>write the handler; however, the handler is expected to actually return a FutureOr<int> (which is a special type denoting that I can return <code>int</code> and <code>Future&lt;int&gt;</code> as well).</li>
</ol>
<p>In the handler I&rsquo;m returning 213, and I&rsquo;m not sure how I could use this value&hellip;</p>
<p>Here is what I came to:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-dart">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="cl"><span class="kt">void</span> <span class="n">main</span><span class="p">(</span><span class="n">List</span><span class="o">&lt;</span><span class="kt">String</span><span class="o">&gt;</span> <span class="n">args</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">compute</span><span class="p">(</span><span class="nl">throwing:</span> <span class="kc">true</span><span class="p">).</span><span class="n">onError</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="n">error</span><span class="p">,</span> <span class="n">stackTrace</span><span class="p">){</span><span class="n">_handleError</span><span class="p">(</span><span class="n">error</span> <span class="o">as</span> <span class="n">MyError</span><span class="p">)</span> <span class="p">;</span> <span class="k">return</span> <span class="m">213</span><span class="p">;</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="nl">test:</span> <span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="o">=&gt;</span><span class="n">e</span> <span class="k">is</span> <span class="n">MyError</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>
<p>Oh. I forgot about the code in <code>.then(....)</code> block! Let&rsquo;s add it:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-dart">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="cl"><span class="kt">void</span> <span class="n">main</span><span class="p">(</span><span class="n">List</span><span class="o">&lt;</span><span class="kt">String</span><span class="o">&gt;</span> <span class="n">args</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">compute</span><span class="p">(</span><span class="nl">throwing:</span> <span class="kc">true</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">.</span><span class="n">then</span><span class="p">((</span><span class="n">v</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">print</span><span class="p">(</span><span class="n">v</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}).</span><span class="n">onError</span><span class="p">((</span><span class="n">error</span><span class="p">,</span> <span class="n">stackTrace</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">_handleError</span><span class="p">(</span><span class="n">error</span> <span class="o">as</span> <span class="n">MyError</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="m">213</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span> <span class="nl">test:</span> <span class="p">(</span><span class="n">e</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="n">e</span> <span class="k">is</span> <span class="n">MyError</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>
<p>Now Dart recognized that a future in <code>then</code> does not return a Future with int value; it just returns <code>void</code>. Providing an <code>int</code> value in <code>onError</code> is compilation error. Is this really what happens? <a href="https://www.youtube.com/watch?v=juPtFTifgvM" target="_blank" rel="noopener noreffer ">What if I&rsquo;m wrong?</a></p>
<p>Let&rsquo;s pretend out business case is to take computed value and then classify the value as being small or big.  We have a classification function <code>Future&lt;Size&gt; classify(int)</code>:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-dart">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="cl"><span class="n">enum</span> <span class="n">Size</span> <span class="p">{</span><span class="n">small</span><span class="p">,</span> <span class="n">big</span><span class="p">,</span> <span class="n">unspecified</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">Future</span><span class="o">&lt;</span><span class="n">Size</span><span class="o">&gt;</span> <span class="n">classify</span><span class="p">(</span><span class="kt">int</span> <span class="n">number</span><span class="p">)</span> <span class="kd">async</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="n">number</span> <span class="o">&gt;</span> <span class="m">100</span> <span class="o">?</span>  <span class="n">Size</span><span class="p">.</span><span class="n">big</span> <span class="o">:</span> <span class="n">Size</span><span class="p">.</span><span class="n">small</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>
<p>Using this function on <code>then(...)</code>:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-dart">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="cl"><span class="kt">void</span> <span class="n">mainf</span><span class="p">(</span><span class="n">List</span><span class="o">&lt;</span><span class="kt">String</span><span class="o">&gt;</span> <span class="n">args</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">compute</span><span class="p">(</span><span class="nl">throwing:</span> <span class="kc">true</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">.</span><span class="n">then</span><span class="p">(</span><span class="n">classify</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">.</span><span class="n">onError</span><span class="p">((</span><span class="n">error</span><span class="p">,</span> <span class="n">stackTrace</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">_handleError</span><span class="p">(</span><span class="n">error</span> <span class="o">as</span> <span class="n">MyError</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span> <span class="nl">test:</span> <span class="p">(</span><span class="n">e</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="n">e</span> <span class="k">is</span> <span class="n">MyError</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>
<p>raises compilation error.
From vscode:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-bash">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">The body might <span class="nb">complete</span> normally, causing <span class="s1">&#39;null&#39;</span> to be returned, but the <span class="k">return</span> type, <span class="s1">&#39;FutureOr&lt;Size&gt;&#39;</span>, is a potentially non-nullable type.
</span></span><span class="line"><span class="cl"> Try adding either a <span class="k">return</span> or a throw statement at the end.</span></span></code></pre></div></div>
<p>Or from dart:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-bash">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">Error: A non-null value must be returned since the <span class="k">return</span> <span class="nb">type</span> <span class="s1">&#39;FutureOr&lt;Size&gt;&#39;</span> doesn<span class="s1">&#39;t allow null.
</span></span></span><span class="line"><span class="cl"><span class="s1"> - &#39;</span>Size<span class="s1">&#39; is from &#39;</span>main.dart<span class="err">&#39;</span>.
</span></span><span class="line"><span class="cl">  .onError<span class="o">((</span>error, stackTrace<span class="o">)</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">           ^</span></span></code></pre></div></div>
<h2 id="fix-it-provide-correct-the-completion-value">Fix it: provide correct the completion value</h2>
<p>Aha! Let&rsquo;s fix that by providing <code>Size.unspecified</code>:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-dart">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="cl"><span class="kt">void</span> <span class="n">main</span><span class="p">(</span><span class="n">List</span><span class="o">&lt;</span><span class="kt">String</span><span class="o">&gt;</span> <span class="n">args</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">compute</span><span class="p">(</span><span class="nl">throwing:</span> <span class="kc">true</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">.</span><span class="n">then</span><span class="p">(</span><span class="n">classify</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">.</span><span class="n">onError</span><span class="p">((</span><span class="n">error</span><span class="p">,</span> <span class="n">stackTrace</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">_handleError</span><span class="p">(</span><span class="n">error</span> <span class="o">as</span> <span class="n">MyError</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">Size</span><span class="p">.</span><span class="n">unspecified</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span> <span class="nl">test:</span> <span class="p">(</span><span class="n">e</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="n">e</span> <span class="k">is</span> <span class="n">MyError</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>
<p>What is going on here?</p>
<p>Futures can be executed in succession. We are building a &ldquo;pipeline&rdquo; of execution. Each level of execution returns other future (possibly with other type). <code>onError</code>&rsquo;s type of handler function depends on what future we&rsquo;re handling. Although we&rsquo;re handling errors thrown anywhere up the stream, we only need to provide completion value for last future in the chain, i.e. result of <code>classify</code>.</p>
<p>Observe the output of the above execution:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-bash">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">_handleError: My error: calculation exception</span></span></code></pre></div></div>
<h2 id="handling-exception-trown-in-classify">Handling exception trown in <code>classify</code></h2>
<p>If <code>classify</code> threw an exception, what would be the output? I&rsquo;d expect that nothing would change - actually, <code>classify</code> is never called, because exception is thrown higher in the pipe, in compute. What if compute() provides <code>int</code> value, and <code>classify</code> fails? Let&rsquo;s see:</p>
<p>Firs, make <code>classify</code> throw on negative numbers and make compute() use provided result:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-dart">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="cl"><span class="n">Future</span><span class="o">&lt;</span><span class="n">Size</span><span class="o">&gt;</span> <span class="n">classify</span><span class="p">(</span><span class="kt">int</span> <span class="n">number</span><span class="p">)</span> <span class="kd">async</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="p">(</span><span class="n">number</span> <span class="o">&lt;</span> <span class="m">0</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">throw</span> <span class="n">MyError</span><span class="p">(</span><span class="nl">message:</span> <span class="s2">&#34;classify error: negative&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="n">number</span> <span class="o">&gt;</span> <span class="m">100</span> <span class="o">?</span> <span class="n">Size</span><span class="p">.</span><span class="n">big</span> <span class="o">:</span> <span class="n">Size</span><span class="p">.</span><span class="n">small</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">Future</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">compute</span><span class="p">({</span><span class="kt">bool</span> <span class="nl">throwing:</span> <span class="kc">false</span><span class="p">,</span> <span class="kt">int</span> <span class="nl">result:</span> <span class="m">1</span><span class="p">})</span> <span class="kd">async</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="p">(</span><span class="n">throwing</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">throw</span> <span class="n">MyError</span><span class="p">(</span><span class="nl">message:</span> <span class="s1">&#39;calculation exception&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">Future</span><span class="p">.</span><span class="n">delayed</span><span class="p">(</span><span class="n">Duration</span><span class="p">(</span><span class="nl">seconds:</span> <span class="m">2</span><span class="p">),</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="n">result</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>
<p>Now, let&rsquo;s run the example:</p>
<ul>
<li>with negative <code>compute</code> value</li>
<li><code>throwing: false</code>
What would happen?</li>
<li><code>compute</code> would return normally after 2 seconds</li>
<li><code>classify</code> would throw exception</li>
</ul>
<p>So, would onError correctly report <code>classify</code> exception? Let&rsquo;s find out:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-dart">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="cl"><span class="kt">void</span> <span class="n">main</span><span class="p">(</span><span class="n">List</span><span class="o">&lt;</span><span class="kt">String</span><span class="o">&gt;</span> <span class="n">args</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">compute</span><span class="p">(</span><span class="nl">throwing:</span> <span class="kc">false</span><span class="p">,</span> <span class="nl">result:</span> <span class="o">-</span><span class="m">10</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">.</span><span class="n">then</span><span class="p">(</span><span class="n">classify</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">.</span><span class="n">onError</span><span class="p">((</span><span class="n">error</span><span class="p">,</span> <span class="n">stackTrace</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">_handleError</span><span class="p">(</span><span class="n">error</span> <span class="o">as</span> <span class="n">MyError</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">Size</span><span class="p">.</span><span class="n">unspecified</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span> <span class="nl">test:</span> <span class="p">(</span><span class="n">e</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="n">e</span> <span class="k">is</span> <span class="n">MyError</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>
<blockquote>
<p>_handleError: My error: classify error: negative</p>
</blockquote>
<p>&#x1f604; That was easy! onError handles exception thrown somewhere up the chain. Would the same be true for async variant?</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-dart">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="cl"><span class="kt">void</span> <span class="n">main</span><span class="p">(</span><span class="n">List</span><span class="o">&lt;</span><span class="kt">String</span><span class="o">&gt;</span> <span class="n">args</span><span class="p">)</span> <span class="kd">async</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">a</span> <span class="o">=</span> <span class="kd">await</span> <span class="n">compute</span><span class="p">(</span><span class="nl">throwing:</span> <span class="kc">false</span><span class="p">,</span> <span class="nl">result:</span> <span class="o">-</span><span class="m">120</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">Size</span> <span class="n">size</span> <span class="o">=</span> <span class="kd">await</span> <span class="n">classify</span><span class="p">(</span><span class="n">a</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">print</span><span class="p">(</span><span class="n">size</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span> <span class="n">on</span> <span class="n">Exception</span> <span class="k">catch</span> <span class="p">(</span><span class="n">e</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">_handleError</span><span class="p">(</span><span class="n">e</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>
<p>The same output! Great!</p>
<h2 id="using-a-value-in-case-of-exception">Using a value in case of exception</h2>
<p>I&rsquo;m wondering: how can I use the value that onError returned to complete <code>classify</code> returned future? In Future-base variant I can further chain another then(_) call and use the value with which previous Futire was completed with (i.e.Size.unspecified):</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-dart">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="cl"><span class="kt">void</span> <span class="n">main</span><span class="p">(</span><span class="n">List</span><span class="o">&lt;</span><span class="kt">String</span><span class="o">&gt;</span> <span class="n">args</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">compute</span><span class="p">(</span><span class="nl">throwing:</span> <span class="kc">false</span><span class="p">,</span> <span class="nl">result:</span> <span class="o">-</span><span class="m">1</span><span class="p">).</span><span class="n">then</span><span class="p">(</span><span class="n">classify</span><span class="p">).</span><span class="n">onError</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">      <span class="p">(</span><span class="n">error</span><span class="p">,</span> <span class="n">stackTrace</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">_handleError</span><span class="p">(</span><span class="n">error</span> <span class="o">as</span> <span class="n">MyError</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">Size</span><span class="p">.</span><span class="n">unspecified</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span> <span class="nl">test:</span> <span class="p">(</span><span class="n">e</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="n">e</span> <span class="k">is</span> <span class="n">MyError</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">.</span><span class="n">then</span><span class="p">((</span><span class="n">value</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">print</span><span class="p">(</span><span class="s2">&#34;Size is </span><span class="si">$</span><span class="n">value</span><span class="s2">&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>
<p>results in</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-bash">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">_handleError: My error: classify error: negative
</span></span><span class="line"><span class="cl">Size is Size.unspecified</span></span></code></pre></div></div>
<p>and async variant requires explicit asignment in <code>on-catch</code> block:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-dart">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="cl"><span class="kt">void</span> <span class="n">main</span><span class="p">(</span><span class="n">List</span><span class="o">&lt;</span><span class="kt">String</span><span class="o">&gt;</span> <span class="n">args</span><span class="p">)</span> <span class="kd">async</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">Size</span><span class="o">?</span> <span class="n">size</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">a</span> <span class="o">=</span> <span class="kd">await</span> <span class="n">compute</span><span class="p">(</span><span class="nl">throwing:</span> <span class="kc">false</span><span class="p">,</span> <span class="nl">result:</span> <span class="o">-</span><span class="m">1</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">size</span> <span class="o">=</span> <span class="kd">await</span> <span class="n">classify</span><span class="p">(</span><span class="n">a</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">print</span><span class="p">(</span><span class="n">size</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span> <span class="n">on</span> <span class="n">Exception</span> <span class="k">catch</span> <span class="p">(</span><span class="n">e</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">_handleError</span><span class="p">(</span><span class="n">e</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">size</span> <span class="o">=</span> <span class="n">Size</span><span class="p">.</span><span class="n">unspecified</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span> <span class="k">finally</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">print</span><span class="p">(</span><span class="s2">&#34;Size is </span><span class="si">$</span><span class="n">size</span><span class="s2">&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>
<p>So, it seems everything can be done in both variants.</p>
<p>How about timout?</p>
<h1 id="timeout">Timeout</h1>
<p>Let&rsquo;s say that we are presented with a business requirement to return <code>Size.unspecified</code> every time the computation takes longer than 500 ms. In order to test that, let&rsquo;s prepare  <code>compute()</code> so that it would take duration (of type <a href="https://api.dart.dev/stable/2.18.7/dart-core/Duration-class.html" target="_blank" rel="noopener noreffer ">Duration</a>):</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-dart">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="cl"><span class="n">Future</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">compute</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span><span class="kt">bool</span> <span class="nl">throwing:</span> <span class="kc">false</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="nl">result:</span> <span class="m">1</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">Duration</span> <span class="nl">dur:</span> <span class="kd">const</span> <span class="n">Duration</span><span class="p">(</span><span class="nl">seconds:</span> <span class="m">2</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">})</span> <span class="kd">async</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="p">(</span><span class="n">throwing</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">throw</span> <span class="n">MyError</span><span class="p">(</span><span class="nl">message:</span> <span class="s1">&#39;calculation exception&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">Future</span><span class="p">.</span><span class="n">delayed</span><span class="p">(</span><span class="n">dur</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="n">result</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>
<p>So, if we change the <code>compute</code> future to timeout after <code>requestedTimeout</code>, that&rsquo;s all: our <code>on Exception catch (e)</code> block would catch TimeoutException and correctly assign size:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-dart">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="n">maina</span><span class="p">(</span><span class="n">List</span><span class="o">&lt;</span><span class="kt">String</span><span class="o">&gt;</span> <span class="n">args</span><span class="p">)</span> <span class="kd">async</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">Size</span><span class="o">?</span> <span class="n">size</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="n">Duration</span> <span class="n">requestedTimeout</span> <span class="o">=</span> <span class="n">Duration</span><span class="p">(</span><span class="nl">milliseconds:</span> <span class="m">500</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">a</span> <span class="o">=</span> <span class="kd">await</span> <span class="n">compute</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">            <span class="nl">throwing:</span> <span class="kc">false</span><span class="p">,</span> <span class="nl">result:</span> <span class="m">200</span><span class="p">,</span> <span class="nl">dur:</span> <span class="n">Duration</span><span class="p">(</span><span class="nl">seconds:</span> <span class="m">2</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">        <span class="p">.</span><span class="n">timeout</span><span class="p">(</span><span class="n">requestedTimeout</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">size</span> <span class="o">=</span> <span class="kd">await</span> <span class="n">classify</span><span class="p">(</span><span class="n">a</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">print</span><span class="p">(</span><span class="n">size</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span> <span class="n">on</span> <span class="n">Exception</span> <span class="k">catch</span> <span class="p">(</span><span class="n">e</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">_handleError</span><span class="p">(</span><span class="n">e</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">size</span> <span class="o">=</span> <span class="n">Size</span><span class="p">.</span><span class="n">unspecified</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span> <span class="k">finally</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">print</span><span class="p">(</span><span class="s2">&#34;Size is </span><span class="si">$</span><span class="n">size</span><span class="s2">&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>
<p>Output:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-bash">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">_handleError: TimeoutException after 0:00:00.500000: Future not completed
</span></span><span class="line"><span class="cl">Size is Size.unspecified</span></span></code></pre></div></div>
<p>With Future variant some more work is needed. Not only should we set timeout on the future, byt also note that our test function in <code>onError</code> would effectively prevent handlng TimeoutException (it won&rsquo;t allow <code>_handleError</code> to fire as well as won&rsquo;t complete the Future with <code>Size.unspecified</code>).</p>
<p>Setting only timeout in Future variant gives  this output:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-bash">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">Unhandled exception:
</span></span><span class="line"><span class="cl">TimeoutException after 0:00:00.500000: Future not completed</span></span></code></pre></div></div>
<p>Let&rsquo;s relax the test, or actually, let&rsquo;s remove it altogether; we could call <code>_handleError</code> conditionally,  but return (i.e. complete) proper Size unconditionally:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-dart">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="cl"><span class="kt">void</span> <span class="n">mainf</span><span class="p">(</span><span class="n">List</span><span class="o">&lt;</span><span class="kt">String</span><span class="o">&gt;</span> <span class="n">args</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">Duration</span> <span class="n">requestedTimeout</span> <span class="o">=</span> <span class="n">Duration</span><span class="p">(</span><span class="nl">milliseconds:</span> <span class="m">500</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="n">compute</span><span class="p">(</span><span class="nl">throwing:</span> <span class="kc">false</span><span class="p">,</span> <span class="nl">result:</span> <span class="o">-</span><span class="m">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">.</span><span class="n">timeout</span><span class="p">(</span><span class="n">requestedTimeout</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">.</span><span class="n">then</span><span class="p">(</span><span class="n">classify</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">.</span><span class="n">onError</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">      <span class="p">(</span><span class="n">error</span><span class="p">,</span> <span class="n">stackTrace</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">error</span> <span class="k">is</span> <span class="n">MyError</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="n">_handleError</span><span class="p">(</span><span class="n">error</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">Size</span><span class="p">.</span><span class="n">unspecified</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}).</span><span class="n">then</span><span class="p">((</span><span class="n">value</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">print</span><span class="p">(</span><span class="s2">&#34;Size is </span><span class="si">$</span><span class="n">value</span><span class="s2">&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>
<p>Now the above code results in proper handling of required value:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Size is Size.unspecified</span></span></code></pre></div></div>
<h1 id="summary">Summary</h1>
<p>Asynchronous execution syntax, language support or at least a library support is present in almost all major languages:</p>
<ul>
<li><a href="https://docs.scala-lang.org/overviews/core/futures.html" target="_blank" rel="noopener noreffer ">Scala</a></li>
<li><a href="https://rust-lang.github.io/async-book/01_getting_started/04_async_await_primer.html" target="_blank" rel="noopener noreffer ">Rust</a></li>
<li><a href="https://realpython.com/async-io-python/" target="_blank" rel="noopener noreffer ">Python</a></li>
<li><a href="https://javascript.info/async" target="_blank" rel="noopener noreffer ">JavaScript</a></li>
<li><a href="https://dart.dev/codelabs/async-await" target="_blank" rel="noopener noreffer ">Dart</a></li>
</ul>
<p>Sometimes the asynchrony is single-threaded (JS) and sometimes the tasks are scheduled on a number of OS threads (go).</p>
<p>Different approach exist in</p>
<ul>
<li><a href="https://blog.logrocket.com/how-use-go-channels/" target="_blank" rel="noopener noreffer ">Go: channels</a> where goroutines are handled by the runtime (i.e. schedued automatically - by language runtime - for execution on syste threads)</li>
<li><a href="https://docs.oracle.com/en/java/javase/19/docs/api/java.base/java/util/concurrent/CompletableFuture.html" target="_blank" rel="noopener noreffer ">Java with completable futures</a> where currently using Furure-based approach requires thinking about actual executors (and underlying thread pools). <a href="https://wiki.openjdk.org/display/loom" target="_blank" rel="noopener noreffer ">Projec Loom</a> and the arrival of <a href="https://openjdk.org/jeps/428" target="_blank" rel="noopener noreffer ">JEPP 428</a> would introcude <a href="https://www.infoq.com/news/2022/06/java-structured-concurrency/" target="_blank" rel="noopener noreffer ">structured concurrency</a> which furter complicates/simplifies the development of concurrent/asynchronous code.</li>
</ul>
<p>No matter what language you choose, you need to learn the API, write small programs to get used to the API and have a grasp of how to deal with exceptional situations, read, experiment and be ready for all the troubles the async execution environment brings (with non-deterministic behavior, debugging, reasoning about code flow - to name a few).</p>
<p>And don&rsquo;t ever think you know concurrent programming. It is hard (tm) and our carbon-based hardware would always have problems in processing concurrency (both as a concept and as a code).</p>]]></description>
</item>
<item>
    <title>Dart for Java developers</title>
    <link>/posts/2023-01-09-dart/</link>
    <pubDate>Mon, 09 Jan 2023 05:47:54 &#43;0100</pubDate>
    <author>Kamila Chyla</author>
    <guid>/posts/2023-01-09-dart/</guid>
    <description><![CDATA[<div class="featured-image">
                <img src="/dart.png" referrerpolicy="no-referrer">
            </div><p>Welcome in a new series of articles about Dart programming language.</p>
<p>It is not a beginner tutorial. I focus mainly on features that may be surprising and/or interesting for a Java(Script) developer.</p>
<h1 id="slides">Slides</h1>
<p>Slide notes are available <a href="/dart_for_java_devs.pdf" rel="">here</a>.</p>
<h1 id="the-resources">The resources:</h1>
<p>Start with these:&hellip;</p>
<ol>
<li><a href="https://dart.dev/guides/language/language-tour" target="_blank" rel="noopener noreffer ">https://dart.dev/guides/language/language-tour</a>  (language overview)</li>
<li><a href="https://dartpad.dev/" target="_blank" rel="noopener noreffer ">https://dartpad.dev/</a> (write &amp; run in online editor)</li>
<li><a href="https://dart.dev/guides/language/spec" target="_blank" rel="noopener noreffer ">https://dart.dev/guides/language/spec</a> (language specification page, <a href="https://dart.dev/guides/language/specifications/DartLangSpec-v2.10.pdf" target="_blank" rel="noopener noreffer ">current spec pdf: 2.10</a>)</li>
<li><a href="https://dart.dev/guides/language/effective-dart" target="_blank" rel="noopener noreffer ">https://dart.dev/guides/language/effective-dart</a> (good practices)</li>
</ol>
<h2 id="basics">Basics</h2>
<p>&hellip; or look below:</p>
<ol>
<li><code>.dart</code> file is a &ldquo;module&rdquo;.</li>
<li>top-level functions, variables, constants and classes</li>
<li>names starting with &ldquo;_&rdquo; (underscore) are private to the module</li>
<li>everything is an object</li>
<li>null-safety (nullable type by appending <code>?</code> to type name, like in Kotlin)</li>
<li>generics are are reified (accessible at runtime), contrary to Java, where types are erased.</li>
<li>type inference; you can declare variables with <code>var</code>.</li>
<li><code>final</code> modifier makes variable assign-once; <code>const</code> modifier makes variable a compile-time constant.</li>
<li>import from built-in libraries (<code>import 'dart:html';</code>), local filesystem (<code>import './foo.dart</code>) or external package managed by build tool, like <code>pub</code> (<code>import 'package:test/test.dart';</code>)</li>
<li>you can alias a lib, import only one symbol or exclude symbol from import (<code>as</code>, <code>show</code>, <code>hide</code>)</li>
<li>asynchrony support with <code>async</code> and <code>await</code>, <a href="https://api.dart.dev/stable/dart-async/Future-class.html" target="_blank" rel="noopener noreffer ">Future</a> and <a href="https://api.dart.dev/stable/dart-async/Stream-class.html" target="_blank" rel="noopener noreffer ">Stream</a> classes, which are run in same <a href="https://api.dart.dev/stable/dart-isolate" target="_blank" rel="noopener noreffer ">Isolate</a> - see [Concurrency in Dart)[https://api.dart.dev/stable/dart-isolate)</li>
<li>sync and async generator functions</li>
<li>callable classes: instances can be called with params; implement <code>call</code> method in the class</li>
<li><em>isolates</em> as &ldquo;threads&rdquo; without race conditions, see <a href="https://dart.dev/guides/language/concurrency" target="_blank" rel="noopener noreffer ">concurrency</a></li>
<li>typedefs (<code>typedef IntList = List&lt;int&gt;;</code>_), also generic, and (recommended) function types, eg: <code>final bool Function(Event) _predicate</code>  or <code>final List&lt;void Function(Event)&gt; _observers;</code></li>
<li>Control structures: <code>for</code> (with iterator in form <code>for elem of iter</code>), <code>while(){}</code>, <code>do{} while()</code>, <code>switch</code> (without pattern matching)</li>
<li><a href="https://dart.dev/guides/language/extension-methods" target="_blank" rel="noopener noreffer ">Extension methods</a> add functionality to existing classes. Resolve to a static type of the receiver (like in Kotlin).</li>
</ol>
<h2 id="classes">Classes</h2>
<p>As Java developers we usually think in terms of classes. Dart supports classs, allows to define abstract classes and offers mixins (that define behaviors and don&rsquo;t have constructors) with which a class can be extended.</p>
<p>See <a href="https://dart.dev/guides/language/language-tour#classes" target="_blank" rel="noopener noreffer ">classes section in lnguage tour</a>.</p>
<p>If, by any  chance, you are a JavaScript developer, you might want to read a decicated  <a href="https://dart.dev/guides/language/coming-from/js-to-dart" target="_blank" rel="noopener noreffer ">guide for JavaScript prorgammers</a> with examples.</p>
<h2 id="libraries">Libraries</h2>
<p>If you want to dive deep into libraries, start with standard library. Then, depending on the target platform, look at native or javacript secions below.</p>
<h3 id="standard-library">Standard library</h3>
<p>These libraries workk on all platforms:</p>
<ul>
<li><a href="https://api.dart.dev/stable/dart-core/dart-core-library.html" target="_blank" rel="noopener noreffer ">dart:core</a></li>
<li><a href="https://api.dart.dev/stable/dart-async/dart-async-library.html" target="_blank" rel="noopener noreffer ">dart:async</a> and <a href="https://pub.dev/packages/async" target="_blank" rel="noopener noreffer ">package:async</a></li>
<li><a href="https://api.dart.dev/stable/dart-collection/dart-collection-library.html" target="_blank" rel="noopener noreffer ">dart:collection</a> and <a href="https://pub.dev/packages/collection" target="_blank" rel="noopener noreffer ">package:collection</a></li>
<li><a href="https://api.dart.dev/stable/dart-convert/dart-convert-library.html" target="_blank" rel="noopener noreffer ">dart:convert</a> and <a href="https://pub.dev/packages/convert" target="_blank" rel="noopener noreffer ">package:convert</a></li>
<li><a href="https://api.dart.dev/stable/dart-developer/dart-developer-library.html" target="_blank" rel="noopener noreffer ">dart:developer</a> (only in <a href="https://dart.dev/overview#native-platform" target="_blank" rel="noopener noreffer ">Native JIT</a> and <a href="https://dart.dev/tools/dartdevc" target="_blank" rel="noopener noreffer ">dartdevc</a>)</li>
<li><a href="https://api.dart.dev/stable/dart-math/dart-math-library.html" target="_blank" rel="noopener noreffer ">dart:math</a></li>
<li><a href="https://api.dart.dev/stable/dart-typed_data/dart-typed_data-library.html" target="_blank" rel="noopener noreffer ">dart:typed_data</a> (and also <a href="https://pub.dev/packages/typed_data" target="_blank" rel="noopener noreffer ">package:typed_data</a>)</li>
</ul>
<h3 id="dart-native">Dart native</h3>
<p><a href="https://dart.dev/overview#native-platform" target="_blank" rel="noopener noreffer ">Dart native</a> platform allows to create AOT- and JIT-compiled code and provides a few special libraries:</p>
<ul>
<li><a href="https://api.dart.dev/stable/dart-ffi/dart-ffi-library.html" target="_blank" rel="noopener noreffer ">dart:ffi</a> and  <a href="https://pub.dev/packages/ffi" target="_blank" rel="noopener noreffer ">package:ffi</a></li>
<li><a href="https://api.dart.dev/stable/dart-io/dart-io-library.html" target="_blank" rel="noopener noreffer ">dart:io</a> and <a href="https://pub.dev/packages/io" target="_blank" rel="noopener noreffer ">package:io</a></li>
<li><a href="https://api.dart.dev/stable/dart-isolate/dart-isolate-library.html" target="_blank" rel="noopener noreffer ">dart:isolate</a></li>
<li><a href="https://api.dart.dev/stable/dart-mirrors/dart-mirrors-library.html" target="_blank" rel="noopener noreffer ">dart:mirrors</a></li>
</ul>
<h3 id="javascript">Javascript</h3>
<p><a href="https://dart.dev/overview#web-platform" target="_blank" rel="noopener noreffer ">Dart Web platform</a> allows developing for web.</p>
<ul>
<li><a href="https://api.dart.dev/stable/dart-html/dart-html-library.html" target="_blank" rel="noopener noreffer ">dart:html</a></li>
<li><a href="https://api.dart.dev/stable/dart-indexed_db/dart-indexed_db-library.html" target="_blank" rel="noopener noreffer ">dart:indexed_db</a></li>
<li><a href="https://api.dart.dev/stable/dart-js/dart-js-library.html" target="_blank" rel="noopener noreffer ">dart:js</a></li>
<li><a href="https://api.dart.dev/stable/dart-js_util/dart-js_util-library.html" target="_blank" rel="noopener noreffer ">dart:js_util</a></li>
<li><a href="https://pub.dev/packages/js" target="_blank" rel="noopener noreffer ">package:js</a> - also  <a href="https://dart.dev/web/js-interop" target="_blank" rel="noopener noreffer ">JavaScript interoperability</a></li>
<li><a href="https://api.dart.dev/stable/dart-svg/dart-svg-library.html" target="_blank" rel="noopener noreffer ">dart:svg</a></li>
<li><a href="https://api.dart.dev/stable/dart-web_audio/dart-web_audio-library.html" target="_blank" rel="noopener noreffer ">dart:web_audio</a></li>
<li><a href="https://api.dart.dev/stable/dart-web_gl/dart-web_gl-library.html" target="_blank" rel="noopener noreffer ">dart:web_gl</a></li>
</ul>
<h2 id="nice-cookbook-articles">Nice cookbook articles:</h2>
<p>The <a href="https://docs.flutter.dev/cookbook" target="_blank" rel="noopener noreffer ">cookbook</a> is a nice collection of hints on how to implement specific Dart/Flutter usecases, for example: <a href="https://docs.flutter.dev/cookbook/networking/background-parsing#4-move-this-work-to-a-separate-isolate" target="_blank" rel="noopener noreffer ">parsing json in backgroud</a>, <a href="https://docs.flutter.dev/cookbook/navigation/returning-data" target="_blank" rel="noopener noreffer ">return data from screen</a>, <a href="https://docs.flutter.dev/cookbook/networking/authenticated-requests" target="_blank" rel="noopener noreffer ">make authenticated requests</a> or <a href="https://docs.flutter.dev/cookbook/persistence/sqlite" target="_blank" rel="noopener noreffer ">persist data with sqlite</a>, <a href="https://docs.flutter.dev/cookbook/testing/integration/introduction" target="_blank" rel="noopener noreffer ">how to write integration tests</a>&hellip;</p>
<h1 id="next-steps">Next steps</h1>
<p>As a next step, we may want to write some short prorgams just to check out some ideas and get used to the language itself. Stay tuned!</p>
<h1 id="happy-coding">Happy coding!</h1>
]]></description>
</item>
</channel>
</rss>
