<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Creative Bracket]]></title><description><![CDATA[Creative Bracket is the go-to Dart resource blog on the Dart language and tools with easy to understand Dart tutorials and videos for your next project.]]></description><link>https://creativebracket.hashnode.dev</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1725540848969/ecea3e05-51b8-4ba9-928d-82e83fee6607.png</url><title>Creative Bracket</title><link>https://creativebracket.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Tue, 03 Nov 2026 02:33:09 GMT</lastBuildDate><atom:link href="https://creativebracket.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Supabase & Riverpod Minicourse | Build A Realtime Photo Sharing App]]></title><description><![CDATA[We will build a realtime photo sharing Flutter app with Supabase and Riverpod.]]></description><link>https://creativebracket.hashnode.dev/supabase-riverpod-minicourse-build-a-realtime-photo-sharing-app</link><guid isPermaLink="true">https://creativebracket.hashnode.dev/supabase-riverpod-minicourse-build-a-realtime-photo-sharing-app</guid><category><![CDATA[Dart]]></category><category><![CDATA[Flutter]]></category><category><![CDATA[supabase]]></category><category><![CDATA[#dart-for-beginners]]></category><category><![CDATA[dart programming tutorial]]></category><dc:creator><![CDATA[Creative Bracket Blog]]></dc:creator><pubDate>Tue, 25 Apr 2023 11:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1726188861978/68a5645f-7a96-47b2-b920-2ccbaa44c004.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this free minicourse, we will build a realtime photo sharing app with <a target="_blank" href="https://supabase.com">Supabase</a>, <a target="_blank" href="https://flutter.dev">Flutter</a> and <a target="_blank" href="https://docs-v2.riverpod.dev/">Riverpod</a>. Supabase is an open-source Firebase alternative that offers a set of tools to create scalable and secure web and mobile applications.</p>
<p>Flutter is an open-source framework by Google for building natively compiled, multi-platform applications. The SDK is written in Dart which prides itself as being a flexible, general-purpose programming language which supports both AOT and JIT compilation targets.</p>
<p>On the other hand, Riverpod is a state management library for Flutter that provides a simple, composable way of managing application state. It uses dependency injection to enable sharing state across the app and offers an intuitive API for managing state.</p>
<h2 id="heading-get-started"><strong>Get started</strong></h2>
<p>To get set up and prepped for the course:</p>
<ol>
<li><p><a target="_blank" href="https://github.com/graphicbeacon/supabase_riverpod_minicourse/tree/starter">Get the source code</a> on GitHub. It contains the starting base that we build upon in the course</p>
</li>
<li><p><a target="_blank" href="https://database.new/">Create a Supabase account</a> or spin up a Docker instance. This is a necessary first step to create our Supabase project</p>
</li>
<li><p><a target="_blank" href="https://docs.flutter.dev/get-started/install">Install the Flutter SDK</a>. This is what we’re building our app with.</p>
</li>
</ol>
<h2 id="heading-package-dependencies"><strong>Package Dependencies</strong></h2>
<p>There are several dependencies that are added to the project, though the important ones are:</p>
<h3 id="heading-supabaseflutterhttpspubdevpackagessupabaseflutter"><a target="_blank" href="https://pub.dev/packages/supabase_flutter"><strong>supabase_flutter</strong></a></h3>
<p>This contains the client library for interacting with Supabase. Creating a Supabase account and project will expose a <strong>Project url</strong> as well as an <strong>API key</strong>. These will enable you to initialise Supabase by doing the following:</p>
<pre><code class="lang-dart"><span class="hljs-keyword">import</span> <span class="hljs-string">'package:supabase_flutter/supabase_flutter.dart'</span>;

<span class="hljs-keyword">void</span> main() <span class="hljs-keyword">async</span> {
  WidgetsFlutterBinding.ensureInitialized();

  <span class="hljs-keyword">await</span> Supabase.initialize(
    url: <span class="hljs-string">'SUPABASE_URL'</span>,
    anonKey: <span class="hljs-string">'SUPABASE_ANON_KEY'</span>,
  );

  runApp(MyApp());
}
</code></pre>
<p>Initialising Supabase successfully gives you access to the <code>SupabaseClient</code> objects by doing the following:</p>
<pre><code class="lang-dart"><span class="hljs-keyword">final</span> supabase = Supabase.instance.client;
</code></pre>
<h3 id="heading-flutterriverpodhttpspubdevpackagesflutterriverpod"><a target="_blank" href="https://pub.dev/packages/flutter_riverpod"><strong>flutter_riverpod</strong></a></h3>
<p>This allows using the riverpod state management solution in a Flutter project. We will be creating several Providers and Notifier instances via Code Generation, available via Riverpod 2+.</p>
<p>Here is a snippet of how creating a Provider that exposes a <em>Repository</em> client looks like:</p>
<pre><code class="lang-dart"><span class="hljs-comment">// file: memory_repository.dart</span>

<span class="hljs-keyword">import</span> <span class="hljs-string">'package:riverpod_annotation/riverpod_annotation.dart'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'package:supabase_flutter/supabase_flutter.dart'</span>;

<span class="hljs-keyword">part</span> <span class="hljs-string">'memory_repository.g.dart'</span>;

<span class="hljs-meta">@riverpod</span>
MemoryRepository memoryRepository(MemoryRepositoryRef _) =&gt; MemoryRepository();

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MemoryRepository</span> </span>{
  <span class="hljs-keyword">final</span> _client = Supabase.instance.client;

  Future getMemories() <span class="hljs-keyword">async</span> {
    <span class="hljs-keyword">return</span> _client.from(<span class="hljs-string">'memories'</span>).select(<span class="hljs-string">'id, title, image_id'</span>)
      .order(<span class="hljs-string">'created_at'</span>);
  }
}
</code></pre>
<p>You’ll then be able to generate the relevant <code>AutoDisposeProvider&lt;MemoryRepository&gt;</code> object by running the following:</p>
<pre><code class="lang-bash">$ flutter pub run build_runner build
</code></pre>
<p>When listening to authentication state changes, the <code>StreamProvider&lt;T&gt;</code> object is quite effective for sharing the Supabase authentication state:</p>
<pre><code class="lang-dart"><span class="hljs-comment">// file: auth_user.dart</span>

<span class="hljs-keyword">import</span> <span class="hljs-string">'package:riverpod_annotation/riverpod_annotation.dart'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'package:supabase_flutter/supabase_flutter.dart'</span>;

<span class="hljs-keyword">part</span> <span class="hljs-string">'auth_user.g.dart'</span>;

<span class="hljs-meta">@riverpod</span>
Stream&lt;User?&gt; authUser(AuthUserRef ref) <span class="hljs-keyword">async</span>* {
  <span class="hljs-keyword">final</span> authStream = Supabase.instance.client.auth.onAuthStateChange;

  <span class="hljs-keyword">await</span> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">final</span> authState <span class="hljs-keyword">in</span> authStream) {
    <span class="hljs-keyword">yield</span> authState.session?.user;
  }
}
</code></pre>
<h2 id="heading-watch-full-minicourse"><strong>Watch full minicourse</strong></h2>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/510QYduXBXc">https://youtu.be/510QYduXBXc</a></div>
<p> </p>
<p><a target="_blank" href="https://github.com/graphicbeacon/supabase_riverpod_minicourse">Get the source code</a></p>
]]></content:encoded></item><item><title><![CDATA[Firebase Authentication and Flutter Full Course]]></title><description><![CDATA[We will build a messaging app with Firebase Authentication and Flutter. Includes Cloud Firestore for data persistence.]]></description><link>https://creativebracket.hashnode.dev/firebase-authentication-and-flutter-full-course-2020</link><guid isPermaLink="true">https://creativebracket.hashnode.dev/firebase-authentication-and-flutter-full-course-2020</guid><category><![CDATA[Dart]]></category><category><![CDATA[Firebase]]></category><category><![CDATA[Flutter]]></category><category><![CDATA[#dart-for-beginners]]></category><category><![CDATA[dart programming tutorial]]></category><dc:creator><![CDATA[Creative Bracket Blog]]></dc:creator><pubDate>Fri, 20 Nov 2020 12:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1726188560495/f71d100c-821e-457c-bdf5-335091a84d97.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Firebase is a platform that provides the infrastructure needed to build apps fast. In the <a target="_blank" href="https://creativebracket.com/fullstack-flutter-mongodb-mini-course/">previous</a> mini-course we built a mobile and web app with Flutter and MongoDB. In this full course we will build a messaging app with Firebase Authentication and Flutter.</p>
<p>We begin by setting up a Flutter project from scratch and building the general look and feel of our messaging UI. We then create a Firebase project while setting up and configuring our Android and Web applications. We will set up Firebase Authentication with the <a target="_blank" href="https://pub.dev/packages/google_sign_in"><strong>google_sign_in</strong></a> package and Cloud Firestore for storing our chat messages. We will learn how to set up the correct security rules to ensure only authenticated users are allowed to write data to our collection.</p>
<h2 id="heading-watch-full-course">Watch full course</h2>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/oyVDDRczuJI">https://youtu.be/oyVDDRczuJI</a></div>
<p> </p>
<p>and the finale…</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/9zBWglEaGuQ">https://youtu.be/9zBWglEaGuQ</a></div>
<p> </p>
<h2 id="heading-set-up-flutter-project"><strong>Set up Flutter project</strong></h2>
<p>Before creating a Flutter project we need to enable Flutter Web support since we will also be running this app in the Web browser. Run the following commands to enable Flutter Web support:</p>
<pre><code class="lang-bash">$ flutter channel beta <span class="hljs-comment"># checkout the beta channel</span>
$ flutter upgrade
$ flutter config --enable-web
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726188588923/26493a2a-0d55-4f3e-baf9-c249c3ffe491.png" alt class="image--center mx-auto" /></p>
<p>With Flutter Web enabled you can proceed to create your Flutter project:</p>
<pre><code class="lang-bash">$ flutter create my_messaging_app
</code></pre>
<p>After that process is complete open the directory in your editor of choice, whether Visual Studio Code or Android Studio as the <em>recommended</em> editors for Flutter development.</p>
<p>Ensure you have the relevant extensions installed for your editors. In the case of Visual Studio Code you need the <a target="_blank" href="https://dartcode.org/">Dart Code extensions</a>. For Android Studio search for “Flutter” in the plugins repository under <strong>Configure</strong> &gt; <strong>Plugins</strong>.</p>
<h2 id="heading-run-the-flutter-project"><strong>Run the Flutter project</strong></h2>
<p>Launch any of the device simulators using the steps in Visual Studio Code below. This assumes you have the listed simulators already set up using AVD Manager in Android Studio or any other means. Make sure that the simulator you select has Play Store support enabled.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726210689583/09baacfc-041c-4b5e-bbaa-55a18a376809.png" alt class="image--center mx-auto" /></p>
<p>You can run a Flutter project by typing the <code>flutter run</code> command in the Terminal and hitting <code>Enter</code>. Alternatively you can use the editor controls to run your Flutter app.</p>
<h2 id="heading-build-ui-for-firebase-authentication"><strong>Build UI for Firebase Authentication</strong></h2>
<p>Open <strong>lib/main.dart</strong> and refactor the <code>MyApp</code> StatelessWidget like so:</p>
<pre><code class="lang-dart"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyApp</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">StatelessWidget</span> </span>{
  <span class="hljs-meta">@override</span>
  Widget build(BuildContext context) {
    <span class="hljs-keyword">return</span> MaterialApp(
      title: <span class="hljs-string">"The Chat Crew"</span>, <span class="hljs-comment">// &lt;== Change this line</span>
      debugShowCheckedModeBanner: <span class="hljs-keyword">false</span>, <span class="hljs-comment">// &lt;== Add this line</span>
      theme: ThemeData(
        primarySwatch: Colors.purple, <span class="hljs-comment">// &lt;== Change this line</span>
      ),
      home: MyHomePage(title: <span class="hljs-string">"The Chat Crew"</span>), <span class="hljs-comment">// &lt;== Change this line</span>
    );
  }
}
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726210753099/f21a6468-1433-4928-8b9c-9a69942b0b8c.png" alt class="image--center mx-auto" /></p>
<p>Refactor the <code>_MyHomePageState</code> class by removing the <code>_incrementCounter()</code> method and <code>_counter</code> field.</p>
<pre><code class="lang-dart"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">_MyHomePageState</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">State</span>&lt;<span class="hljs-title">MyHomePage</span>&gt; </span>{
  <span class="hljs-comment">// int _counter = 0;</span>

  <span class="hljs-comment">// void _incrementCounter() {</span>
  <span class="hljs-comment">//  setState(() {</span>
  <span class="hljs-comment">//    _counter++;</span>
  <span class="hljs-comment">//  });</span>
  <span class="hljs-comment">// }</span>

  <span class="hljs-meta">@override</span>
  Widget build(BuildContext context) { ... }
}
</code></pre>
<p>In the <code>build()</code> method remove the <code>floatingActionButton:</code> section of the <code>Scaffold()</code> widget and the two <code>Text()</code> widgets rendered in the <code>Column()</code> children. In fact you should have the code below once you’ve taken out the unnecessary bits:</p>
<pre><code class="lang-dart"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">_MyHomePageState</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">State</span>&lt;<span class="hljs-title">MyHomePage</span>&gt; </span>{
  <span class="hljs-meta">@override</span>
  Widget build(BuildContext context) {
    <span class="hljs-keyword">return</span> Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        centerTitle: <span class="hljs-keyword">true</span>, <span class="hljs-comment">// &lt;== Added this line</span>
      ),
      backgroundColor: Color(<span class="hljs-number">0xffdee2d6</span>), <span class="hljs-comment">// &lt;== Added this line</span>
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: &lt;Widget&gt;[],
      ),
    );
  }
}
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726210799145/a9d43201-541a-4970-9dd1-09d46dca7be6.png" alt class="image--center mx-auto" /></p>
<p>The section below the app bar of the app consists of a message wall to display chat messages and the bottom area which will show either the sign in button or the message form.</p>
<p>The message wall will be rendered in an <code>Expanded()</code> widget since that takes up most of the screen real estate.</p>
<pre><code class="lang-dart">body: Column(
  mainAxisAlignment: MainAxisAlignment.center,
  children: &lt;Widget&gt;[
    Expanded(
      child: Container(),
    ),
  ],
),
</code></pre>
<p>To display the Sign in button, install the <a target="_blank" href="https://pub.dev/packages/flutter_signin_button"><strong>flutter_signin_button</strong></a> package:</p>
<pre><code class="lang-bash">$ pub global activate crawl <span class="hljs-comment"># install the crawl cli</span>
$ crawl add flutter_signin_button
</code></pre>
<p>Import <strong>flutter_signin_button</strong> and display after the <code>Expanded()</code> widget:</p>
<pre><code class="lang-dart"><span class="hljs-keyword">import</span> <span class="hljs-string">'package:flutter_signin_button/flutter_signin_button.dart'</span>;

..

body: Column(
  mainAxisAlignment: MainAxisAlignment.center,
  children: &lt;Widget&gt;[
    Expanded(
      child: Container(),
    ),
    Container(
      padding: <span class="hljs-keyword">const</span> EdgeInsets.all(<span class="hljs-number">5</span>),
      child: SignInButton(
        Buttons.Google,
        padding: <span class="hljs-keyword">const</span> EdgeInsets.all(<span class="hljs-number">5</span>),
        onPressed: () {},
      ),
    ),
  ],
),
</code></pre>
<p><strong>Stop the whole app and start again</strong> in order to load the image assets required to display the Google logo on the sign in button.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726210902568/a6a49847-a8e9-4ef7-aabc-9065bf1ec131.png" alt class="image--center mx-auto" /></p>
<p><a target="_blank" href="https://youtu.be/oyVDDRczuJI"><strong>Watch the full course</strong></a> for details on completing the sign in and sign out flows.</p>
]]></content:encoded></item><item><title><![CDATA[Fullstack Flutter and MongoDB Cloud Mini-Course]]></title><description><![CDATA[We will build a contacts list application with Dart and Flutter that manages contacts in MongoDB Cloud Atlas database.]]></description><link>https://creativebracket.hashnode.dev/fullstack-flutter-and-mongodb-cloud-mini-course</link><guid isPermaLink="true">https://creativebracket.hashnode.dev/fullstack-flutter-and-mongodb-cloud-mini-course</guid><category><![CDATA[Dart]]></category><category><![CDATA[Flutter]]></category><category><![CDATA[MongoDB]]></category><category><![CDATA[dart programming tutorial]]></category><category><![CDATA[fullstackdevelopment]]></category><dc:creator><![CDATA[Creative Bracket Blog]]></dc:creator><pubDate>Tue, 06 Oct 2020 11:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1726187533765/d75906cf-6d72-48ce-8724-478829b29559.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>After numerous requests to produce a Flutter and MongoDB combo, I’ve devoted the time to produce a fullstack Flutter and MongoDb Cloud mini-course. We will build a contacts list application that manages contacts in MongoDB Cloud Atlas database. We will also implement a Dart backend server for talking to MongoDB datastore. This app will be built for both Flutter mobile and web platforms.</p>
<h2 id="heading-watch-full-mini-course">Watch full mini course</h2>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/juKDXPk7kU4">https://youtu.be/juKDXPk7kU4</a></div>
<p> </p>
<p><a target="_blank" href="https://github.com/graphicbeacon/flutter_mongodb_contacts_app">Get the source code</a></p>
<h2 id="heading-getting-started"><strong>Getting started</strong></h2>
<p>You will need a <a target="_blank" href="https://www.mongodb.com/cloud">MongoDB Cloud Account</a> to create a Project and Cluster. This will give us an environment with MongoDB installed and a user to connect to that MongoDB instance.</p>
<p>The contents of the mini-course are as follows:</p>
<ul>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=juKDXPk7kU4&amp;t=0s">00:00</a> Intro</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=juKDXPk7kU4&amp;t=7s">00:07</a> App Demo</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=juKDXPk7kU4&amp;t=128s">02:08</a> Setup MongoDB Cloud Atlas Project and Cluster</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=juKDXPk7kU4&amp;t=198s">03:18</a> Connect to MongoDB Cluster via Terminal</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=juKDXPk7kU4&amp;t=272s">04:32</a> Examine codebase and dependencies</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=juKDXPk7kU4&amp;t=313s">05:13</a> Connect to MongoDB from codebase</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=juKDXPk7kU4&amp;t=374s">06:14</a> Create server and initial route</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=juKDXPk7kU4&amp;t=450s">07:30</a> Add POST and DELETE endpoints</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=juKDXPk7kU4&amp;t=599s">09:59</a> Implement initial contacts screen</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=juKDXPk7kU4&amp;t=704s">11:44</a> Implements “No contacts” view</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=juKDXPk7kU4&amp;t=821s">13:41</a> Implement contact addition functionality</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=juKDXPk7kU4&amp;t=899s">14:59</a> Style ListTile widget</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=juKDXPk7kU4&amp;t=982s">16:22</a> Refactor NoContacts widget</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=juKDXPk7kU4&amp;t=1021s">17:01</a> Create ContactListing widget</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=juKDXPk7kU4&amp;t=1100s">18:20</a> Using the Faker package</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=juKDXPk7kU4&amp;t=1133s">18:53</a> Adding contact deletion functionality</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=juKDXPk7kU4&amp;t=1207s">20:07</a> Implements ContactsApi class</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=juKDXPk7kU4&amp;t=1406s">23:26</a> Create Contact PODO</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=juKDXPk7kU4&amp;t=1701s">28:21</a> Implement contact creation method on api class</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=juKDXPk7kU4&amp;t=1791s">29:51</a> Running app on Flutter Web</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=juKDXPk7kU4&amp;t=2224s">37:04</a> Outro</p>
</li>
</ul>
<p>Clone and check out the <code>starter</code> branch on the <a target="_blank" href="https://github.com/graphicbeacon/flutter_mongodb_contacts_app">Github repo</a>. This will provide the correct setup to follow along in the Fullstack Flutter and MongoDB Cloud mini-course.</p>
<p>The Dart packages included in this mini-course are:</p>
<ol>
<li><p><strong>sevr</strong> – a Dart library inspired by ExpressJS for writing HTTP servers. We use this to write a server that communicates with our MongoDB Cloud Cluster.</p>
</li>
<li><p><strong>dio</strong> – a powerful HTTP client for Dart. We use this to make requests to our Dart backend server.</p>
</li>
<li><p><strong>faker</strong> – a library that generates various fake data. We use this to generate the contact names of our Fullstack Flutter app.</p>
</li>
<li><p><strong>mongo_dart</strong> – a library for communicating with MongoDB databases. This allows us to talk to MongoDb Cloud Atlas.</p>
</li>
</ol>
<h2 id="heading-implementing-the-server"><strong>Implementing the server</strong></h2>
<p>In <strong>server/lib/server.dart</strong> initiate a connection to MongoDB Cloud Atlas:</p>
<pre><code class="lang-dart"><span class="hljs-keyword">import</span> <span class="hljs-string">'package:mongo_dart/mongo_dart.dart'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'package:sevr/sevr.dart'</span>;

<span class="hljs-keyword">void</span> start() <span class="hljs-keyword">async</span> {
  <span class="hljs-comment">// Log into database</span>
  <span class="hljs-keyword">final</span> db = <span class="hljs-keyword">await</span> Db.create(
      <span class="hljs-string">'mongodb+srv://&lt;user&gt;:&lt;password&gt;@cluster0.xpkap.mongodb.net/&lt;dbname&gt;?retryWrites=true&amp;w=majority'</span>);
  <span class="hljs-keyword">await</span> db.open(); <span class="hljs-comment">// Initiate the connection</span>
  <span class="hljs-keyword">final</span> coll = db.collection(<span class="hljs-string">'contacts'</span>); <span class="hljs-comment">// Define a handle to the contacts collection</span>
}
</code></pre>
<p>The database connection string can be found by clicking the “<strong>CONNECT</strong>” button on your cluster and then selecting “<strong>Connect your application</strong>” as the connection method.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726187605513/d6e60040-40ae-4ff1-bbf9-e05465a69626.png" alt class="image--center mx-auto" /></p>
<p>Opening a connection to our MongoDB Cloud Cluster means we can create a server that acts as a gateway to our database:</p>
<pre><code class="lang-dart"><span class="hljs-keyword">void</span> start() <span class="hljs-keyword">async</span> {
  <span class="hljs-comment">// Log into database</span>
  ..
  <span class="hljs-comment">// Create server</span>
  <span class="hljs-keyword">const</span> port = <span class="hljs-number">8081</span>;
  <span class="hljs-keyword">final</span> serv = Sevr();
}
</code></pre>
<p>Our HTTP server is contained within the <code>sevr</code> variable which allows us to go ahead and define our first route:</p>
<pre><code class="lang-dart"><span class="hljs-keyword">void</span> start() <span class="hljs-keyword">async</span> {
  <span class="hljs-comment">// Log into database</span>
  ..
  <span class="hljs-comment">// Create server</span>
  <span class="hljs-keyword">const</span> port = <span class="hljs-number">8081</span>;
  <span class="hljs-keyword">final</span> serv = Sevr();

  <span class="hljs-comment">// Define routes</span>
  serv.<span class="hljs-keyword">get</span>(<span class="hljs-string">'/'</span>, [
    (ServRequest req, ServResponse res) <span class="hljs-keyword">async</span> {
      <span class="hljs-keyword">final</span> contacts = <span class="hljs-keyword">await</span> coll.find().toList();
      <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">200</span>).json({<span class="hljs-string">'contacts'</span>: contacts});
    }
  ]);
}
</code></pre>
<p>Our first route describes a path and the data to be returned for any client that makes a request to it, in this case being a <code>GET</code> request to the root route of our server. We are returning the list of contacts in our MongoDb collection.</p>
<p>To activate our server and routes we need to listen to incoming connections:</p>
<pre><code class="lang-dart"><span class="hljs-keyword">void</span> start() <span class="hljs-keyword">async</span> {
  <span class="hljs-comment">// Log into database</span>
  ..
  <span class="hljs-comment">// Create server</span>
  ..
  <span class="hljs-comment">// Define routes</span>
  ..
  <span class="hljs-comment">// Listen for connections</span>
  serv.listen(port, callback: () {
    <span class="hljs-built_in">print</span>(<span class="hljs-string">'Server listening on port: <span class="hljs-subst">$port</span>'</span>);
  });
}
</code></pre>
<p>Running this in the terminal will give you the output below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726187668503/abcb18a8-61a8-4abb-8e34-dbaa37408fdb.png" alt class="image--center mx-auto" /></p>
<p><a target="_blank" href="https://youtu.be/juKDXPk7kU4">Watch full mini course</a></p>
<p><a target="_blank" href="https://github.com/graphicbeacon/flutter_mongodb_contacts_app">Get the source code</a></p>
]]></content:encoded></item><item><title><![CDATA[Google Cloud Platform and Flutter Mini-Course released]]></title><description><![CDATA[In this mini course we will build an Image Upload App that communicates with Google Cloud Platform and Flutter SDK for cross-platform apps.]]></description><link>https://creativebracket.hashnode.dev/google-cloud-platform-and-flutter-mini-course-released</link><guid isPermaLink="true">https://creativebracket.hashnode.dev/google-cloud-platform-and-flutter-mini-course-released</guid><category><![CDATA[Dart]]></category><category><![CDATA[Flutter]]></category><category><![CDATA[Google Cloud Platform]]></category><category><![CDATA[dart programming tutorial]]></category><category><![CDATA[Flutter Examples]]></category><dc:creator><![CDATA[Creative Bracket Blog]]></dc:creator><pubDate>Fri, 25 Sep 2020 11:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1726187365440/6378bc44-6220-46b4-a3b2-efdbeb6b6f99.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Becoming a full-stack developer requires a hand in all layers of the application development stack. This includes Frontend, Backend, Database and Infrastructure.</p>
<p>Google Cloud Platform is a suite of cloud computing services used by Google and external business for running various kinds of software. This platform contains relevant services allowing us to be effective in building full-stack applications.</p>
<p>In this mini course we will build an Image Upload Mobile App using a couple of Dart packages primarily <a target="_blank" href="https://pub.dev/packages/gcloud">gcloud</a> and <a target="_blank" href="https://pub.dev/packages/googleapis_auth">googleapis_auth</a>. These packages provide a set of helper classes for connecting to Google Cloud Platform services.</p>
<p>We will be using the <a target="_blank" href="https://flutter.dev/">Flutter SDK</a> to build our mobile app since it provides a great set of features and tools for building cross-platform mobile applications. It also makes sense to be using Flutter as it’s also written in Dart :)</p>
<h2 id="heading-watch-full-mini-course">Watch full Mini course</h2>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/CV0vGWDtCR0">https://youtu.be/CV0vGWDtCR0</a></div>
<p> </p>
<p><a target="_blank" href="https://github.com/graphicbeacon/gcloud_flutter_image_upload">Get the source code</a></p>
<h2 id="heading-getting-started"><strong>Getting started</strong></h2>
<p>We need to set up a <a target="_blank" href="https://cloud.google.com/">Google Cloud Platform</a> account. It’s free to set up and they’re currently offering $300 credit for 90 days. This will allow you enough time to use the Cloud Storage service for uploading images to.</p>
<p>The contents of the mini course below are as follows:</p>
<ul>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=CV0vGWDtCR0&amp;t=0s">00:00</a> Intro</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=CV0vGWDtCR0&amp;t=19s">00:19</a> App demo</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=CV0vGWDtCR0&amp;t=57s">00:57</a> Create a Google Cloud Project</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=CV0vGWDtCR0&amp;t=92s">01:32</a> Create a Cloud Storage bucket</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=CV0vGWDtCR0&amp;t=131s">02:11</a> Setup dependencies</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=CV0vGWDtCR0&amp;t=163s">02:43</a> Implement image picker</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=CV0vGWDtCR0&amp;t=391s">06:31</a> Create your IAM Service Account</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=CV0vGWDtCR0&amp;t=471s">07:51</a> Implement CloudApi Service class</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=CV0vGWDtCR0&amp;t=574s">09:34</a> Load IAM credentials into CloudApi Service</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=CV0vGWDtCR0&amp;t=661s">11:01</a> Make request to Google Cloud Storage</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=CV0vGWDtCR0&amp;t=730s">12:10</a> Set correct content type for image</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=CV0vGWDtCR0&amp;t=871s">14:31</a> Set custom metadata on image</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=CV0vGWDtCR0&amp;t=908s">15:08</a> Implement loading and uploaded state</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=CV0vGWDtCR0&amp;t=1019s">16:59</a> Set bucket access permissions</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=CV0vGWDtCR0&amp;t=1066s">17:46</a> Outro</p>
</li>
</ul>
<p>Once you’ve set up a Google Cloud Platform account, create a Flutter project by running the following command:</p>
<pre><code class="lang-bash">$ flutter create new_project
</code></pre>
<p>Add the following packages under the <code>dependencies</code> key of your <strong>pubspec.yaml</strong> file:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">dependencies:</span> 
  <span class="hljs-attr">gcloud:</span> <span class="hljs-string">^0.7.3</span>
  <span class="hljs-attr">googleapis_auth:</span> <span class="hljs-string">^0.2.12</span>
  <span class="hljs-attr">image_picker:</span> <span class="hljs-string">^0.6.7+10</span>
  <span class="hljs-attr">mime:</span> <span class="hljs-string">^0.9.7</span>
</code></pre>
<p>Then run <code>pub get</code> to update your packages. Once you are setup, see the course for the full demonstration.</p>
<p><a target="_blank" href="https://youtu.be/CV0vGWDtCR0">Watch on YouTube</a></p>
<p><a target="_blank" href="https://github.com/graphicbeacon/gcloud_flutter_image_upload">Get the source code</a></p>
]]></content:encoded></item><item><title><![CDATA[Manage Dart packages with Crawl]]></title><description><![CDATA[Crawl helps you manage Dart packages in your projects. It provides an interactive prompt for creating pubspec files with some helpful commands.]]></description><link>https://creativebracket.hashnode.dev/manage-dart-packages-with-crawl</link><guid isPermaLink="true">https://creativebracket.hashnode.dev/manage-dart-packages-with-crawl</guid><category><![CDATA[Dart]]></category><category><![CDATA[#dart language]]></category><category><![CDATA[dart-packages]]></category><dc:creator><![CDATA[Creative Bracket Blog]]></dc:creator><pubDate>Thu, 24 Sep 2020 11:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1726186537460/8b4e2b6a-3983-4387-961a-5110d54580e3.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Although we’ve got tools like Stagehand to generate the boilerplate for a Dart project, a pain-point I’ve experienced regularly is managing Dart packages. Whenever I needed to add a new package, I usually followed the steps below:</p>
<ol>
<li><p>Lookup package details on pub.dev</p>
</li>
<li><p>Hit the <strong>Installing</strong> tab and copy the latest version</p>
</li>
<li><p>Open my <strong>pubspec.yaml</strong> file in the Dart project</p>
</li>
<li><p>Add the package and version to <code>dependencies</code> or <code>dev_dependencies</code> list</p>
</li>
<li><p>Save file.</p>
</li>
<li><p>Run <code>pub get</code> to update my packages</p>
</li>
</ol>
<p>Having programmed in Nodejs I was aware of the <strong>npm</strong> tool which provided the <code>init</code> and <code>install</code> commands to automate the creation and maintenance of packages.</p>
<p>After searching around I came across the Pubspec Assist extension for VS Code that enabled me to search and install a package through the UI. It works in most cases but I wasn’t content that I had to be in the editor in order to use it! So instead of complaining I decided I’ll write my own.</p>
<h2 id="heading-introducing-crawl"><strong>Introducing Crawl</strong></h2>
<p>Crawl helps you manage Dart packages in your <strong>pubspec.yaml</strong> files. It borrows inspiration from the <strong>npm</strong> tool and will be familiar if you have used it.</p>
<p>The only pre-requisite is the <a target="_blank" href="https://dart.dev/">Dart</a> runtime and you can install Crawl by running <code>pub global activate crawl</code>. This will enable the <code>crawl</code> executable in your terminal.</p>
<p>To launch the usage screen simply run <code>crawl</code> in your terminal:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726186566577/161f15b7-19b4-4afc-8135-36047f6b0a3b.png" alt class="image--center mx-auto" /></p>
<p>To create a new pubspec.yaml file enter <code>crawl init</code> in your terminal and follow the interactive prompt:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726186589713/c565e37a-6f86-450f-86b2-56f62be5378e.png" alt class="image--center mx-auto" /></p>
<p>To add a new package run the following command:</p>
<pre><code class="lang-bash">$ crawl install -p &lt;package-name&gt; <span class="hljs-comment"># eg: `crawl install -p shelf`</span>
$ crawl install -p &lt;package-name&gt; -v &lt;version&gt; <span class="hljs-comment"># eg: `crawl install -p shelf -v 0.7.9`</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726186614695/41c360ef-4295-40d2-a6e2-88f16306fcb6.png" alt class="image--center mx-auto" /></p>
<p>To remove a package run the following command:</p>
<pre><code class="lang-bash">$ crawl uninstall &lt;package-name&gt;
</code></pre>
<p>This package is still early days, but currently you are able to:</p>
<ol>
<li><p>Create a pubspec.yaml file</p>
</li>
<li><p>Add to <code>dependencies</code> including specifying a particular version</p>
</li>
<li><p>Add to <code>dev_dependencies</code> including specifying a particular version</p>
</li>
<li><p>Run <code>pub get</code> automatically to update project dependencies</p>
</li>
<li><p>Uninstall package</p>
</li>
<li><p>List unused dependencies in project</p>
</li>
<li><p>Lookup package information on Pub repository</p>
</li>
</ol>
<p>Try it out and let me know what you think ? Although the Dart team will be introducing a <code>pub add</code> and <code>pub remove</code> command in the next release, this tool provides other commands that will be useful in your projects.</p>
<p><a target="_blank" href="https://pub.dev/packages/crawl">Get the package</a></p>
]]></content:encoded></item><item><title><![CDATA[Flutter for React developers (Video series)]]></title><description><![CDATA[Flutter borrows inspiration from React with some notable improvements around performance and consistency. Learn more in this video series.]]></description><link>https://creativebracket.hashnode.dev/flutter-for-react-developers-video-series</link><guid isPermaLink="true">https://creativebracket.hashnode.dev/flutter-for-react-developers-video-series</guid><category><![CDATA[Dart]]></category><category><![CDATA[Flutter]]></category><category><![CDATA[React Native]]></category><category><![CDATA[dart programming tutorial]]></category><category><![CDATA[#dart-for-beginners]]></category><dc:creator><![CDATA[Creative Bracket Blog]]></dc:creator><pubDate>Mon, 02 Mar 2020 12:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1726185975425/fde915d7-5f9f-45f9-a536-9a53c5da1409.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Picking the right tools for development is important when building a good app. The common mantra “<strong>write once, deploy everywhere</strong>” has proven to be effective from solutions like Phonegap or Ionic or NativeScript.</p>
<p>Flutter is a contender by Google designed to enable developers to build cross-platform applications. These applications will run on the web, mobile and desktop. It’s also written in Dart, which makes it easy to pick up in a couple of hours.</p>
<p>Flutter is mainly inspired by React with some noteworthy improvements. For example apps written for mobile are compiled <em>ahead-of-time</em> to machine code, so that means that the underlying language the app was written in does not enter production. This carries the benefit of not having to ship with the Dart VM, thus, drastically reducing app size and increasing performance.</p>
<h2 id="heading-part-1">Part 1</h2>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/arIeSpgMZ7M">https://youtu.be/arIeSpgMZ7M</a></div>
<p> </p>
<h2 id="heading-part-2">Part 2</h2>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/Uxt7ycYNNHI">https://youtu.be/Uxt7ycYNNHI</a></div>
<p> </p>
<p>Thanks for watching!</p>
]]></content:encoded></item><item><title><![CDATA[Angel Dart Framework Tutorial Series]]></title><description><![CDATA[Angel is a backend framework for developing applications. We will build a CMS for managing blog articles with validation and search functionality.]]></description><link>https://creativebracket.hashnode.dev/angel-dart-framework-tutorial-series</link><guid isPermaLink="true">https://creativebracket.hashnode.dev/angel-dart-framework-tutorial-series</guid><category><![CDATA[Dart]]></category><category><![CDATA[#dart-for-beginners]]></category><category><![CDATA[dart programming tutorial]]></category><dc:creator><![CDATA[Creative Bracket Blog]]></dc:creator><pubDate>Sun, 26 Jan 2020 12:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1726185642057/84356012-a4ee-4f49-bc1f-00bddead1101.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this video series we will look at the Angel Framework for backend Dart development, written by Tobe Osakwe, a CS student. Angel comes batteries-included with dozens of plugins, enabling a “plug-and-play” approach to developing production quality applications. We will build a CMS for managing blog articles with validation and search functionality.</p>
<h2 id="heading-part-1">Part 1</h2>
<p>We will bootstrap an Angel project, define our routes and configure our Angel server. We will build the html templates for our Articles screen.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/iPbM10mvpko">https://youtu.be/iPbM10mvpko</a></div>
<p> </p>
<h2 id="heading-part-2">Part 2</h2>
<p>We will learn about services and model classes, utilising code generation tooling to generate classes that serialize our data for persistence layer. We will create a MongoService responsible for facilitating communication with our MongoDb database.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/jM9-JtIbokQ">https://youtu.be/jM9-JtIbokQ</a></div>
<p> </p>
<h2 id="heading-part-3">Part 3</h2>
<p>We will learn how to preview articles saved to the database, as well as implement validation of our input with error handling to ensure that we aren’t submitting invalid data.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/dMIdLiwksUE">https://youtu.be/dMIdLiwksUE</a></div>
<p> </p>
<h2 id="heading-part-4">Part 4</h2>
<p>We will add edit and delete features to our articles.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/3T4iYYgpCJw">https://youtu.be/3T4iYYgpCJw</a></div>
<p> </p>
<h2 id="heading-part-5">Part 5</h2>
<p>We will look at search and navigation toggling.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/MxlOjq1UGrs">https://youtu.be/MxlOjq1UGrs</a></div>
<p> </p>
<p>Thanks for watching!</p>
<p><a target="_blank" href="https://github.com/graphicbeacon/angel_dart_cms_tutorial">Get the source code</a></p>
]]></content:encoded></item><item><title><![CDATA[Implement your own File upload server]]></title><description><![CDATA[We will implement a file upload server that will receive images uploaded via a form. We will use the mime package to parse the sent files.]]></description><link>https://creativebracket.hashnode.dev/implement-your-own-file-upload-server</link><guid isPermaLink="true">https://creativebracket.hashnode.dev/implement-your-own-file-upload-server</guid><category><![CDATA[Dart]]></category><category><![CDATA[#dart language]]></category><category><![CDATA[#dart-for-beginners]]></category><category><![CDATA[dart programming tutorial]]></category><dc:creator><![CDATA[Creative Bracket Blog]]></dc:creator><pubDate>Mon, 25 Nov 2019 12:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1726183429056/338f52c3-1f19-4dfa-9ddb-85f444ecab60.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this tutorial we will learn how to extract file data sent via a form and persist that to server’s filesystem. We will learn more about the multipart/form-data content type and how to use the <a target="_blank" href="https://pub.dev/packages/mime">mime</a> package to extract images from our payload. Some great tips in this lesson so watch till the end!!!</p>
<h2 id="heading-watch-video-tutorial">Watch video tutorial</h2>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/hSkD3y9HMro">https://youtu.be/hSkD3y9HMro</a></div>
<p> </p>
<h2 id="heading-set-up-the-project"><strong>Set up the project</strong></h2>
<p>Create a project folder and bootstrap a console-based project using Stagehand:</p>
<pre><code class="lang-bash">$ stagehand console-full
</code></pre>
<p>Open the <strong>pubspec.yaml</strong> file and add a dependency for the <strong>mime</strong> package:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">dependencies:</span>
  <span class="hljs-attr">mime:</span> <span class="hljs-string">^0.9.6+3</span>
</code></pre>
<p>Update your dependencies by running <code>pub get</code> in your terminal.</p>
<p>Below is the solution from the video tutorial:</p>
<pre><code class="lang-dart"><span class="hljs-comment">// main.dart</span>

<span class="hljs-keyword">import</span> <span class="hljs-string">'dart:io'</span>;

<span class="hljs-keyword">import</span> <span class="hljs-string">'package:mime/mime.dart'</span>;

main() <span class="hljs-keyword">async</span> {
  <span class="hljs-keyword">var</span> server = <span class="hljs-keyword">await</span> HttpServer.bind(<span class="hljs-string">'localhost'</span>, <span class="hljs-number">8085</span>);

  server.listen((request) <span class="hljs-keyword">async</span> {
    <span class="hljs-keyword">if</span> (request.uri.path != <span class="hljs-string">'/fileupload'</span>) {
      request.response
        ..headers.contentType = ContentType.html
        ..write(<span class="hljs-string">'''
          &lt;html&gt;
          &lt;head&gt;
            &lt;title&gt;Image Upload Server&lt;/title&gt;
          &lt;/head&gt;
          &lt;body&gt;
            &lt;form method="post" action="/fileupload" enctype="multipart/form-data"&gt;
              &lt;input type="file" name="fileupload" /&gt;&lt;br /&gt;&lt;br /&gt;
              &lt;button type="submit"&gt;Upload to server&lt;/button&gt;
            &lt;/form&gt;
          &lt;/body&gt;
          &lt;/html&gt;
        '''</span>);
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-comment">// accessing /fileupload endpoint</span>
      <span class="hljs-built_in">List</span>&lt;<span class="hljs-built_in">int</span>&gt; dataBytes = [];

      <span class="hljs-keyword">await</span> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> data <span class="hljs-keyword">in</span> request) {
        dataBytes.addAll(data);
      }

      <span class="hljs-built_in">String</span> boundary = request.headers.contentType.parameters[<span class="hljs-string">'boundary'</span>];
      <span class="hljs-keyword">final</span> transformer = MimeMultipartTransformer(boundary);
      <span class="hljs-keyword">final</span> uploadDirectory = <span class="hljs-string">'./upload'</span>;

      <span class="hljs-keyword">final</span> bodyStream = Stream.fromIterable([dataBytes]);
      <span class="hljs-keyword">final</span> parts = <span class="hljs-keyword">await</span> transformer.bind(bodyStream).toList();

      <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> <span class="hljs-keyword">part</span> <span class="hljs-keyword">in</span> parts) {
        <span class="hljs-built_in">print</span>(<span class="hljs-keyword">part</span>.headers);
        <span class="hljs-keyword">final</span> contentDisposition = <span class="hljs-keyword">part</span>.headers[<span class="hljs-string">'content-disposition'</span>];
        <span class="hljs-keyword">final</span> filename = <span class="hljs-built_in">RegExp</span>(<span class="hljs-string">r'filename="([^"]*)"'</span>)
            .firstMatch(contentDisposition)
            .group(<span class="hljs-number">1</span>);
        <span class="hljs-keyword">final</span> content = <span class="hljs-keyword">await</span> <span class="hljs-keyword">part</span>.toList();

        <span class="hljs-keyword">if</span> (!Directory(uploadDirectory).existsSync()) {
          <span class="hljs-keyword">await</span> Directory(uploadDirectory).create();
        }

        <span class="hljs-keyword">await</span> File(<span class="hljs-string">'<span class="hljs-subst">$uploadDirectory</span>/<span class="hljs-subst">$filename</span>'</span>).writeAsBytes(content[<span class="hljs-number">0</span>]);
      }
    }

    <span class="hljs-keyword">await</span> request.response.close();
  });
}
</code></pre>
<p><a target="_blank" href="https://gist.github.com/graphicbeacon/c25ffe49dade93003742bc43cc21147b">Get the source code</a></p>
]]></content:encoded></item><item><title><![CDATA[Build a User Authentication system (Part 2)]]></title><description><![CDATA[We will learn to login and logout registered users, as well as persist their logged in sessions in MongoDB database.]]></description><link>https://creativebracket.hashnode.dev/build-a-user-authentication-system-part-2</link><guid isPermaLink="true">https://creativebracket.hashnode.dev/build-a-user-authentication-system-part-2</guid><category><![CDATA[Dart]]></category><category><![CDATA[dart programming tutorial]]></category><category><![CDATA[#dart-for-beginners]]></category><category><![CDATA[MongoDB]]></category><category><![CDATA[authentication]]></category><dc:creator><![CDATA[Creative Bracket Blog]]></dc:creator><pubDate>Thu, 07 Nov 2019 12:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1726184542251/065cffd0-9418-46b3-b444-3e1345eb9e2f.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In <a target="_blank" href="https://creativebracket.com/build-a-user-authentication-system-1">part 1</a> we implemented the registration flow as part of adding a user to our database. We learnt about the recommended approach to storing passwords in the database using the SHA256 algorithm to convert our password into a string ‘hash’ combined with a salt.</p>
<p>In this part we will look at the login and logout journeys for our registered user. At the end of this article you will be comfortable understanding and writing basic user authentication systems.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/rHJxHSJY-8k">https://youtu.be/rHJxHSJY-8k</a></div>
<p> </p>
<p><a target="_blank" href="https://youtu.be/rHJxHSJY-8k">Watch on YouTube</a></p>
<h2 id="heading-1-create-the-login-route">1. Create the login route</h2>
<p>In <code>bin/main.dart</code> we have a couple of <code>if</code> statements checking the route and action of the request and responding accordingly to it.</p>
<p>Let’s add another condition within the request listener block for a <code>GET</code> to <code>/login</code>:</p>
<pre><code class="lang-dart">...
server.listen((HttpRequest request) <span class="hljs-keyword">async</span> {
  <span class="hljs-comment">// ...</span>
  <span class="hljs-comment">// ...</span>

  <span class="hljs-comment">// Check a `GET` on `/login`</span>
  <span class="hljs-keyword">if</span> (method == <span class="hljs-string">'GET'</span> &amp;&amp; path == <span class="hljs-string">'/login'</span>) {
    response.write(renderHtml(<span class="hljs-string">'''
      &lt;h1&gt;Login&lt;/h1&gt;
      &lt;form action="/login" method="post"&gt;
        &lt;input type="text" name="username" placeholder="Enter your username" /&gt;
        &lt;input type="password" name="password" placeholder="Enter your password" /&gt;
        &lt;button&gt;Go to the dashboard&lt;/button&gt;
      &lt;/form&gt;
    '''</span>, <span class="hljs-string">'Login to your Account'</span>));
  }

  <span class="hljs-keyword">await</span> response.close();

});
</code></pre>
<p>Running <code>dart bin/main.dart</code> and visiting <a target="_blank" href="http://localhost:8089/login"><code>http://localhost:8089/login</code></a> should display the screen below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726183657756/aa12c11f-b87b-4ca0-8b05-0e43ffb35aea.png" alt class="image--center mx-auto" /></p>
<p>Submitting the form will attempt to post the results to the backend which will result in am empty response. We need the logic to receive whatever we have entered into the form and use that to give the user access.</p>
<h2 id="heading-2-listen-for-the-posted-credentials-and-attempt-to-log-in-the-user"><strong>2. Listen for the posted credentials and attempt to log in the user</strong></h2>
<p>Here’s what we need to do:</p>
<ol>
<li><p>Define a conditional statement to check for <code>POST</code> request to <code>/login</code></p>
</li>
<li><p>Parse the POST request payload which is sent as <code>application/x-www-form-urlencoded</code> content type</p>
</li>
<li><p>Find the user in the database with the matching username. If the user exists we will receive an object with the username, hashed password and salt.</p>
</li>
<li><p>Take the salt from the retrieved user and pass that into our <code>hashPassword</code> function (<em>this was created in Part 1</em>) along with the password the user has provided for logging in</p>
</li>
<li><p>Attempt to match the generated hash in step 3 with the hashed password already stored in the database. If they match then log the user in. If not respond with an error message.</p>
</li>
<li><p>Create a randomised string value to represent the logged in user. This will be stored in a separate MongoDB collection to represent the logged in user.</p>
</li>
<li><p>Redirect the user to the <strong>/dashboard</strong> route</p>
</li>
</ol>
<p>Here’s the logic covering the first two steps:</p>
<pre><code class="lang-dart">
server.listen((HttpRequest request) {
  <span class="hljs-comment">// ...</span>
  <span class="hljs-comment">// ...</span>

  <span class="hljs-comment">// 1. Check for `POST` on `/login`</span>
  <span class="hljs-keyword">if</span> (method == <span class="hljs-string">'POST'</span> &amp;&amp; path == <span class="hljs-string">'/login'</span>) {
    <span class="hljs-comment">// 2. Parse the payload</span>
    <span class="hljs-keyword">var</span> content = <span class="hljs-keyword">await</span> request.transform(Utf8Decoder()).join();
    <span class="hljs-keyword">var</span> params = <span class="hljs-built_in">Uri</span>.splitQueryString(content);
    <span class="hljs-keyword">var</span> user = params[<span class="hljs-string">'username'</span>];
    <span class="hljs-keyword">var</span> password = params[<span class="hljs-string">'password'</span>];

    <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> 3. Find the user in the database with matching details</span>

    <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> 4. Take salt and hash provided password</span>

    <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> 5. Compare hash and login user. Or respond with error</span>

    <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> 6. Create a string-based token to represent the logged in user</span>

    <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> 7. Redirect the user to the /dashboard route</span>

  }

  <span class="hljs-keyword">await</span> response.close();
});
</code></pre>
<p>We are using the same logic to parse the payload like we did in Part 1 during the registration journey. Perhaps we should create a function that takes the request as input, run the parsing logic and return the credentials. <em>I would challenge you to look at how you can do that. If you can’t inform me by posting a comment below.</em></p>
<p>Here’s the logic for step 3:</p>
<pre><code class="lang-dart">server.listen((HttpRequest request) {
  <span class="hljs-comment">// ...</span>
  <span class="hljs-comment">// ...</span>

  <span class="hljs-comment">// 1. Check for `POST` on `/login`</span>
  <span class="hljs-keyword">if</span> (method == <span class="hljs-string">'POST'</span> &amp;&amp; path == <span class="hljs-string">'/login'</span>) {
    <span class="hljs-comment">// 2. Parse the payload</span>
    <span class="hljs-keyword">var</span> content = <span class="hljs-keyword">await</span> request.transform(Utf8Decoder()).join();
    <span class="hljs-keyword">var</span> params = <span class="hljs-built_in">Uri</span>.splitQueryString(content);
    <span class="hljs-keyword">var</span> user = params[<span class="hljs-string">'username'</span>];
    <span class="hljs-keyword">var</span> password = params[<span class="hljs-string">'password'</span>];

    <span class="hljs-comment">// 3. Find the user in the database with matching details</span>
    <span class="hljs-keyword">var</span> user = <span class="hljs-keyword">await</span> store.findOne(where.eq(<span class="hljs-string">'username'</span>, username));
    <span class="hljs-keyword">if</span> (user == <span class="hljs-keyword">null</span>) {
      response..statusCode = HttpStatus.notAuthorised
              ..write(<span class="hljs-string">'Incorrect user and/or password'</span>);
    }
  }
  <span class="hljs-comment">// ...</span>
});
</code></pre>
<p><a target="_blank" href="https://youtu.be/rHJxHSJY-8k">Watch video for complete steps on YouTube</a></p>
]]></content:encoded></item><item><title><![CDATA[Conquering Code Generation in Dart (Video Series)]]></title><description><![CDATA[We will be exploring the tooling made available for Code Generation for Dart projects.]]></description><link>https://creativebracket.hashnode.dev/conquering-code-generation-in-dart</link><guid isPermaLink="true">https://creativebracket.hashnode.dev/conquering-code-generation-in-dart</guid><category><![CDATA[Dart]]></category><category><![CDATA[#dart language]]></category><category><![CDATA[dart programming tutorial]]></category><dc:creator><![CDATA[Creative Bracket Blog]]></dc:creator><pubDate>Fri, 04 Oct 2019 11:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1726182483166/55cc54c4-2322-47ee-9245-7316b90c481d.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Code Generation describes the process of automatically generating code that one would otherwise write by hand. In this new series we will be exploring the tooling made available for Code Generation in Dart projects.</p>
<p>This has been one of the least covered and understood topics due to the lack of documentation on it. We will conquer this tooling beast and grow your confidence in its usage.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/H4HWB2Pmgcw">https://youtu.be/H4HWB2Pmgcw</a></div>
<p> </p>
<p><a target="_blank" href="https://youtu.be/H4HWB2Pmgcw">Watch Part 1 on YouTube</a></p>
<p><a target="_blank" href="https://github.com/graphicbeacon/codegeneration_with_dart">Get the source code</a></p>
<h2 id="heading-how-to-get-started"><strong>How to get started</strong></h2>
<p>Code Generation is available through a package called <a target="_blank" href="https://pub.dev/packages/build"><strong>build</strong></a>. This package exposes a set of interfaces for creating what are known as <em>Builders</em>. A <code>Builder</code> is where you define the business logic to instruct the build process on how to generate code.</p>
<p>Although we encapsulate our logic inside a <code>Builder</code> class, we need a way to run this builder, and that’s where <a target="_blank" href="https://pub.dev/packages/build_runner">build_runner</a> comes in. It runs the build process based on configuration defined inside a <code>build.yaml</code> file. In order for it to understand this <code>build.yaml</code> configuration, the <a target="_blank" href="https://pub.dev/packages/build_config">build_config</a> package is used to parse the instructions defined therein. Therefore the <strong>build_runner</strong> package uses <strong>build_config</strong> behind the scenes.</p>
<p>To create the files for the project, use the <a target="_blank" href="http://localhost:8080/generate-the-scaffolding-for-your-next-project/"><strong>stagehand</strong></a> tool to scaffold a console application:</p>
<pre><code class="lang-bash">$ mkdir code_generators &amp;&amp; <span class="hljs-built_in">cd</span> code_generators
$ stagehand console-full
</code></pre>
<p>Open the pubspec.yaml file and update <code>dependencies</code> and <code>dev_dependencies</code>:</p>
<pre><code class="lang-yaml"><span class="hljs-string">...</span>
<span class="hljs-attr">dependencies:</span>
  <span class="hljs-attr">build:</span> <span class="hljs-string">^1.1.6</span>
  <span class="hljs-attr">path:</span> <span class="hljs-string">^1.6.0</span>
  <span class="hljs-attr">markdown:</span> <span class="hljs-string">^2.0.3</span>

<span class="hljs-attr">dev_dependencies:</span>
  <span class="hljs-attr">build_config:</span> <span class="hljs-string">^0.4.1+1</span>
  <span class="hljs-attr">build_runner:</span> <span class="hljs-string">^1.6.6</span>
  <span class="hljs-attr">pedantic:</span> <span class="hljs-string">^1.7.0</span>
  <span class="hljs-attr">test:</span> <span class="hljs-string">^1.5.0</span>
</code></pre>
<p>Update all your dependencies by running <code>pub get</code>.</p>
<h2 id="heading-configuring-the-buildyaml-file"><strong>Configuring the</strong> <code>build.yaml</code> file</h2>
<p>The <code>build.yaml</code> file contains configuration for <strong>targets</strong>, <strong>builders</strong>, and <strong>post process builders</strong>. The <code>builders</code> configuration allows you to register the builders you have implemented, as well as the top-level function to invoke in order to run the build process for the builder in question. You would also set the <code>build_extensions</code> key with the same value as was set in the <code>buildExtensions</code> member of your <code>Builder</code> class the configuration relates to. The <code>targets</code> config allows you to configure your builder to run on a subset of files in your project, as well as specify if they are enabled or not.</p>
<p>Here’s a typical example registering our <code>CopyBuilder</code> and configuring a target for it:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">targets:</span>
  <span class="hljs-string">$default:</span>
    <span class="hljs-attr">builders:</span>
      <span class="hljs-string">code_generators|copyBuilder:</span>
        <span class="hljs-attr">generate_for:</span>
         <span class="hljs-bullet">-</span> <span class="hljs-string">lib/*</span>
        <span class="hljs-attr">enabled:</span> <span class="hljs-literal">True</span>

<span class="hljs-attr">builders:</span>
  <span class="hljs-attr">copyBuilder:</span>
    <span class="hljs-attr">import:</span> <span class="hljs-string">'package:code_generators/code_generators.dart'</span>
    <span class="hljs-attr">builder_factories:</span> [<span class="hljs-string">'copyBuilder'</span>]
    <span class="hljs-attr">build_extensions:</span>
      <span class="hljs-string">.txt:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-string">.copy.txt</span>
    <span class="hljs-attr">build_to:</span> <span class="hljs-string">source</span>
    <span class="hljs-attr">auto_apply:</span> <span class="hljs-string">dependents</span>
</code></pre>
<p><a target="_blank" href="https://github.com/dart-lang/build/blob/master/build_config/README.md">Learn more about configuring the build.yaml file</a></p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/HnXdsXh_Jdc">https://youtu.be/HnXdsXh_Jdc</a></div>
<p> </p>
<p><a target="_blank" href="https://youtu.be/HnXdsXh_Jdc">Watch Part 2 on YouTube</a></p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/xRJHKb3rekQ">https://youtu.be/xRJHKb3rekQ</a></div>
<p> </p>
<p><a target="_blank" href="https://youtu.be/xRJHKb3rekQ">Watch Part 3 on YouTube</a></p>
<p><a target="_blank" href="https://github.com/graphicbeacon/codegeneration_with_dart">Get the source code</a></p>
<h2 id="heading-further-reading">Further reading</h2>
<ul>
<li><p><a target="_blank" href="https://github.com/dart-lang/source_gen">Dart source_gen package</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/dart-lang/build">Dart build packages repository</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Understanding Reflection and Annotations in Dart]]></title><description><![CDATA[Reflection allows us to examine and modify the structure and behaviour of a program at runtime. We will look at a common use case with Annotations in Dart.]]></description><link>https://creativebracket.hashnode.dev/understanding-reflection-and-annotations-in-dart</link><guid isPermaLink="true">https://creativebracket.hashnode.dev/understanding-reflection-and-annotations-in-dart</guid><category><![CDATA[Dart]]></category><category><![CDATA[#dart language]]></category><dc:creator><![CDATA[Creative Bracket Blog]]></dc:creator><pubDate>Tue, 25 Jun 2019 11:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1726120187989/3a45b1f5-df3f-435e-85ed-9b25e313df81.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this tutorial we will explore the topic of Reflection and how that can be used to write cleaner software. Reflection allows us to examine and modify the structure and behaviour of a program at runtime. We will be working with the <strong>dart:mirrors</strong> library which contains helper classes and functions for achieving this. We will end by looking at a common use case with <strong>Annotations</strong>.</p>
<h2 id="heading-full-video-tutorial">Full video tutorial</h2>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/_2yjPLVEGs4">https://youtu.be/_2yjPLVEGs4</a></div>
<p> </p>
<h2 id="heading-basic-example-with-reflection"><strong>Basic example with Reflection</strong></h2>
<p>Create a <code>main.dart</code> file and start by importing our <strong>dart:mirrors</strong> dependency. Before we implement our reflection logic, let’s also define a class with a method we wish to invoke:</p>
<pre><code class="lang-dart"><span class="hljs-keyword">import</span> <span class="hljs-string">'dart:mirrors'</span>;

main() {
  <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> Implement Reflection logic</span>
}

<span class="hljs-comment">// Our example class to reflect on</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Endpoint</span> </span>{
  handle() =&gt; <span class="hljs-built_in">print</span>(<span class="hljs-string">'Request received'</span>);
}
</code></pre>
<p>To reflect on types and objects we have three methods to work with:</p>
<ol>
<li><p><code>reflect()</code>: Reflects on an instance of a class</p>
</li>
<li><p><code>reflectClass()</code>: Reflects on a class declaration</p>
</li>
<li><p><code>reflectType()</code> Reflects on the type passed in as the argument</p>
</li>
</ol>
<p>In our use case we will use <code>reflect()</code>. Let’s instantiate <code>Endpoint</code> and invoke the handle method via reflection:</p>
<pre><code class="lang-dart">main() {
  <span class="hljs-keyword">var</span> reflectedClass = reflect(Endpoint());

  <span class="hljs-comment">// Invoke the handle() method</span>
  reflectedClass.invoke(<span class="hljs-built_in">Symbol</span>(<span class="hljs-string">'handle'</span>), []);
}
</code></pre>
<p>And then let’s run this file:</p>
<pre><code class="lang-bash">$ dart /path/to/main.dart
</code></pre>
<p>Reflecting an instance provides us with an <code>InstanceMirror</code> that exposes the <code>invoke()</code> method. The members of our instance are depicted as <code>Symbol</code> types. The example above invokes the handle method by passing its <code>Symbol</code>ic name along with an array of positional arguments if any are specified.</p>
<p>To pass arguments across, let’s modify the signature of the <code>handle()</code> method:</p>
<pre><code class="lang-dart">handle(<span class="hljs-built_in">String</span> a) =&gt; <span class="hljs-built_in">print</span>(<span class="hljs-string">'Request received <span class="hljs-subst">$a</span>'</span>);
</code></pre>
<p>And pass this to the invocation:</p>
<pre><code class="lang-dart">reflectedClass.invoke(<span class="hljs-built_in">Symbol</span>(<span class="hljs-string">'handle'</span>), [<span class="hljs-string">'argument 1'</span>]);
<span class="hljs-comment">// =&gt; Request received argument 1</span>
</code></pre>
<p>You can also use the literal form of the <code>handle()</code> symbol:</p>
<pre><code class="lang-dart">reflectedClass.invoke(#handle, [<span class="hljs-string">'argument 1'</span>]);
</code></pre>
<p>You can use the <code>Symbol('methodName')</code> approach if the method name is received as a value from an operation or provided as user input. Ideally when you <strong>don’t</strong> know beforehand the method to invoke.</p>
<p><a target="_blank" href="https://youtu.be/_2yjPLVEGs4">Watch full video tutorial</a></p>
<p><a target="_blank" href="https://gist.github.com/graphicbeacon/9fb6c6a951168d6a31d9b2cc442bcbe2">Get the source code</a></p>
<h2 id="heading-further-reading"><strong>Further reading</strong></h2>
<ul>
<li><p><a target="_blank" href="https://api.dart.dev/stable/2.4.0/dart-mirrors/dart-mirrors-library.html"><strong>dart:mirrors</strong> library documentation</a></p>
</li>
<li><p><a target="_blank" href="https://creativebracket.com/dart-and-mongodb-tutorial-1/">Dart and MongoDB Tutorial #1: Using the mongo_dart package</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Build a User Authentication system (Part 1)]]></title><description><![CDATA[We will learn how to build the obligatory User Authentication system for your next app with Dart and MongoDB.]]></description><link>https://creativebracket.hashnode.dev/build-a-user-authentication-system-1</link><guid isPermaLink="true">https://creativebracket.hashnode.dev/build-a-user-authentication-system-1</guid><category><![CDATA[Dart]]></category><category><![CDATA[dart programming tutorial]]></category><category><![CDATA[#dart-for-beginners]]></category><category><![CDATA[MongoDB]]></category><category><![CDATA[User Authentication]]></category><dc:creator><![CDATA[Creative Bracket Blog]]></dc:creator><pubDate>Mon, 10 Jun 2019 11:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1725975992033/95c1e367-ef12-49e6-9f0a-c35636e9a609.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this two-part series we will learn how to build a User Authentication system for use in your next application. User authentication allows access to specific resources on a system by verifying that a user has valid access to that resource.</p>
<p>Here’s what we will be building:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1725975183561/a91832e7-21ce-459f-9679-b4000e3595f8.gif" alt class="image--center mx-auto" /></p>
<h2 id="heading-prefer-a-video">Prefer a video?</h2>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/HloDTrNH37c">https://youtu.be/HloDTrNH37c</a></div>
<p> </p>
<p><a target="_blank" href="https://youtu.be/HloDTrNH37c">Watch on YouTube</a></p>
<h2 id="heading-pre-requisites"><strong>Pre-requisites</strong></h2>
<p>You need <a target="_blank" href="https://dart.dev/">Dart a</a>nd <a target="_blank" href="https://www.mongodb.com/download-center/community">MongoDB</a> installed. Follow the links or <a target="_blank" href="https://creativebracket.com/dart-and-mongodb-tutorial-1/">check this post out</a> to learn how to set up a MongoDB database. Create a new database called <code>prod</code> with a <code>users</code> collection.</p>
<p>Afterwards let’s set up a project using <strong>Stagehand</strong> by following the steps below:</p>
<ol>
<li><p>Install Stagehand by runnin<a target="_blank" href="https://dart.dev/">g</a> <code>pub global activate stagehand</code></p>
</li>
<li><p>Create your working directory and cd into it: <code>mkdir user_auth &amp;&amp; cd user_auth</code></p>
</li>
<li><p>Run the stagehand command to generate the required files and folders: <code>stagehand console-full</code></p>
</li>
</ol>
<p>Before you update your dependencies, add these packages to the project <code>pubspec.yaml</code> file by replacing the <code>dependencies</code> section:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">dependencies:</span>
  <span class="hljs-attr">crypto:</span> <span class="hljs-string">^2.0.6</span>
  <span class="hljs-attr">mongo_dart:</span> <span class="hljs-string">^0.3.5</span>
  <span class="hljs-attr">uuid:</span> <span class="hljs-string">^2.0.1</span>
</code></pre>
<p>And then run <code>pub get</code>.</p>
<h2 id="heading-1-create-the-server-and-establish-database-connection">1. Create the server and establish database connection</h2>
<p>In <code>bin/main.dart</code> import the dependencies we’ve just installed as well as the inbuilt <code>dart:io</code> library.</p>
<pre><code class="lang-dart"><span class="hljs-keyword">import</span> <span class="hljs-string">'dart:io'</span>;

<span class="hljs-keyword">import</span> <span class="hljs-string">'package:mongo_dart/mongo_dart.dart'</span>;

main() <span class="hljs-keyword">async</span> {  <span class="hljs-comment">// Mark with `async`</span>
  <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> Connect to our Mongo database</span>
  <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> Create our server connection</span>
}
</code></pre>
<p>Let’s write the logic within the <code>main()</code> block to initiate a Mongo connection and define a handle for our “<strong>users</strong>” collection:</p>
<pre><code class="lang-dart">main() <span class="hljs-keyword">async</span> {
  <span class="hljs-comment">// Connect to our Mongo database</span>
  Db db = Db(<span class="hljs-string">'mongodb://localhost:27017/prod'</span>);
  <span class="hljs-keyword">await</span> db.open();
  DbCollection users = db.collection(<span class="hljs-string">'users'</span>);
  <span class="hljs-built_in">print</span>(<span class="hljs-string">'Connected to database!'</span>);

  <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> Create our server connection</span>
}
</code></pre>
<p>Run this file using this command: <code>dart bin/main.dart</code>. If all goes well you should now see the image below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1725975431035/3863ed03-c01a-455d-b826-2eecb42af604.png" alt class="image--center mx-auto" /></p>
<p>And let’s write our server for handling requests and authenticating our user:</p>
<pre><code class="lang-dart">main() <span class="hljs-keyword">async</span> {
  <span class="hljs-comment">// Connect to our Mongo database</span>
  ...
  ...

  <span class="hljs-comment">// Create our server connection</span>
  <span class="hljs-keyword">const</span> port = <span class="hljs-number">8089</span>;
  <span class="hljs-keyword">var</span> server = <span class="hljs-keyword">await</span> HttpServer.bind(<span class="hljs-string">'localhost'</span>, port);

  server.listen((HttpRequest request) {
    <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> Handle request</span>
  });
}
</code></pre>
<p>Should you run that file and <code>curl</code> <a target="_blank" href="http://localhost:8089"><code>http://localhost:8089</code></a> you will get no response. Let’s change that in the next section.</p>
<h2 id="heading-2-return-our-first-response-and-build-the-other-routes"><strong>2. Return our first response and build the other routes</strong></h2>
<p>Let’s update the request listener function, returning our first response to the client:</p>
<pre><code class="lang-dart">server.listen((HttpRequest request) {
  request.response
    ..headers.contentType = ContentType.html
    ..write(<span class="hljs-string">'''
    &lt;html&gt;
      &lt;head&gt;
        &lt;title&gt;User Registration and Login Example&lt;/title&gt;
      &lt;/head&gt;
      &lt;body&gt;
        &lt;h1&gt;Welcome&lt;/h1&gt;
        &lt;p&gt;
          &lt;a href="/login"&gt;Login&lt;/a&gt; or &lt;a href="/register"&gt;Register&lt;/a&gt;
        &lt;/p&gt;
      &lt;/body&gt;
    &lt;/html&gt;
    '''</span>)
    ..close();
});
</code></pre>
<p>Accessing <a target="_blank" href="http://localhost:8089"><strong>http://localhost:8089</strong></a> in your browser should show this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1725975496269/8bbee565-c92c-4933-a956-5f375b2653aa.png" alt class="image--center mx-auto" /></p>
<p>Since we are going to be creating several routes that will serve HTML responses, let us create a helper function that will render the main tags with some interpolated variables. This will save us some extra lines of code.</p>
<p>Outside the main function let’s define a top-level function called <code>renderHtml()</code>:</p>
<pre><code class="lang-dart"><span class="hljs-keyword">void</span> main() {
  ...
}

<span class="hljs-comment">// Render the common html with interpolated strings</span>
renderHtml(<span class="hljs-built_in">String</span> content, [<span class="hljs-built_in">String</span> title = <span class="hljs-string">':)'</span>]) =&gt; <span class="hljs-string">'''
  &lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;<span class="hljs-subst">$title</span>&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    <span class="hljs-subst">$content</span>
  &lt;/body&gt;
  &lt;/html&gt;
'''</span>;
</code></pre>
<p>This will return our main HTML page tags, replacing <code>$content</code> and <code>$title</code>(if defined) variables with the provided values. Now let’s refactor our string passed to <code>response.write()</code> with this function:</p>
<pre><code class="lang-dart">request.response
  ..headers.contentType = ContentType.html
  ..write(renderHtml(
    <span class="hljs-string">'''
    &lt;h1&gt;Welcome&lt;/h1&gt;
      &lt;p&gt;
        &lt;a href="/login"&gt;Login&lt;/a&gt; or &lt;a href="/register"&gt;Register&lt;/a&gt;
      &lt;/p&gt;
    '''</span>,
    <span class="hljs-string">'User Registration and Login Example'</span>,
  ))
  ..close();
</code></pre>
<p>Save and restart the server. Confirm you are still able to access <a target="_blank" href="http://localhost:8089"><strong>http://localhost:8089</strong></a>.</p>
<p>To complete the registration journey, we will create a <code>/register</code> route to handle the user registration flow.</p>
<p>Amend our first response to show only if a <code>GET</code> request is made to the root <code>/</code> of our app:</p>
<pre><code class="lang-dart">server.listen((HttpRequest request) <span class="hljs-keyword">async</span> { <span class="hljs-comment">// Using `async/await`</span>
  <span class="hljs-keyword">var</span> path = request.uri.path;
  <span class="hljs-keyword">var</span> res = request.response;

  res.headers.contentType = ContentType.html;
  res.headers.<span class="hljs-keyword">set</span>(<span class="hljs-string">'Cache-Control'</span>, <span class="hljs-string">'no-cache'</span>);

  <span class="hljs-keyword">if</span> (request.method == <span class="hljs-string">'GET'</span> &amp;&amp; path == <span class="hljs-string">'/'</span>) {
    res.write(renderHtml(
      <span class="hljs-string">'''
      &lt;h1&gt;Welcome&lt;/h1&gt;
        &lt;p&gt;
          &lt;a href="/login"&gt;Login&lt;/a&gt; or &lt;a href="/register"&gt;Register&lt;/a&gt;
        &lt;/p&gt;
      '''</span>,
      <span class="hljs-string">'User Registration and Login Example'</span>,
    ))
  }

  <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> Handle request to other routes</span>

  <span class="hljs-comment">// After all is done, just end the response</span>
  <span class="hljs-keyword">await</span> response.close();
});
</code></pre>
<p>Let’s now look at the request to the <code>/register</code> route. Replace the <code>// TODO:</code> block with this condition:</p>
<pre><code class="lang-dart"><span class="hljs-keyword">if</span> (request.method == <span class="hljs-string">'GET'</span> &amp;&amp; path = <span class="hljs-string">'/register'</span>) {
  res.write(renderHtml(
    <span class="hljs-string">'''
    &lt;h1&gt;Register&lt;/h1&gt;
    &lt;form action="/register" method="post"&gt;
      &lt;input type="text" name="username" placeholder="Enter a username" /&gt;
      &lt;input type="password" name="password" placeholder="Enter a password" /&gt;
      &lt;button&gt;Send&lt;/button&gt;
    &lt;/form&gt;
    '''</span>, <span class="hljs-string">'Create an account'</span>
  ));
}
</code></pre>
<p>Restarting the server will render the screen below when we access <a target="_blank" href="http://localhost:8089/register"><strong>http://localhost:8089/register</strong></a>:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1725975600212/7175937d-04b4-4f92-88d5-784f0a56ef2a.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-3-handle-the-submitted-payload-details-and-create-user"><strong>3. Handle the submitted payload details and create user</strong></h2>
<p>Lastly, we need to handle the form results when it gets submitted to our server. Add another <code>if</code> block to check for <code>POST</code> requests to <code>/register</code>:</p>
<pre><code class="lang-dart"><span class="hljs-keyword">if</span> (method == <span class="hljs-string">'POST'</span> &amp;&amp; path == <span class="hljs-string">'/register'</span>) {
  <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> Retrieve registration details from payload</span>

  <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> Generate a random 'salt'</span>

  <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> Hash the password combining the generated salt</span>

  <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> Store the username, salt and hashed password in the database</span>
}
</code></pre>
<p>During submission of the registration details, the input attribute names and values are sent as a query string to our backend. This means that the encryption type is set to the default <code>application/x-www-form-urlencoded</code>.</p>
<p>We can retrieve the values from our payload using a <code>StreamTransformer&lt;T&gt;</code> to extract the streamed data in our payload. It’s simpler than it sounds.</p>
<p>Firstly we need to import <code>dart:convert</code> library as it contains the <code>Utf8Decoder</code> class for decoding our request payload as a <code>utf-8</code> string:</p>
<pre><code class="lang-dart"><span class="hljs-keyword">import</span> <span class="hljs-string">'dart:io'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'dart:convert'</span>;

...
</code></pre>
<p>And continue by retrieving the registration details from the request payload:</p>
<pre><code class="lang-dart"><span class="hljs-keyword">if</span> (method == <span class="hljs-string">'POST'</span> &amp;&amp; path == <span class="hljs-string">'/register'</span>) {
  <span class="hljs-comment">// Retrieve registration details from payload</span>
  <span class="hljs-keyword">var</span> content = <span class="hljs-keyword">await</span> request.cast&lt;<span class="hljs-built_in">List</span>&lt;<span class="hljs-built_in">int</span>&gt;&gt;().transform(Utf8Decoder()).join();
  <span class="hljs-keyword">var</span> params = <span class="hljs-built_in">Uri</span>.splitQueryString(content);
  <span class="hljs-keyword">var</span> user = params[<span class="hljs-string">'username'</span>];
  <span class="hljs-keyword">var</span> password = params[<span class="hljs-string">'password'</span>];

  <span class="hljs-built_in">print</span>(params);
}
</code></pre>
<p><code>params</code> is a <code>Map&lt;K, V&gt;</code> object containing our details as such:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"username"</span> : <span class="hljs-string">"&lt;the user you entered&gt;"</span>, 
  <span class="hljs-attr">"password"</span>: <span class="hljs-string">"&lt;the password you entered&gt;"</span>
}
</code></pre>
<p>Restart and server, use the registration form and see your terminal output.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1725975693812/c0b442e7-3aef-418c-a7e8-cb6df9ab8acb.png" alt class="image--center mx-auto" /></p>
<p>So passwords are never stored as is in the database due to security reasons. If you already know this then skip this paragraph. It is conventional to create a randomised string called a <strong>salt</strong> which will be combined with a hashing function to produce an output to be stored in the database. The hashed output and the salt will then be stored in the database. Upon logging in the password you provided will be used in combination with the salt we generated earlier to validate the hashed password.</p>
<p>Let’s implement the logic to generate a random salt. Import the <code>dart:math</code> library:</p>
<pre><code class="lang-dart"><span class="hljs-keyword">import</span> <span class="hljs-string">'dart:io'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'dart:convert'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'dart:math'</span>;

...
</code></pre>
<p>And then in the next <code>// TODO:</code> block:</p>
<pre><code class="lang-dart"><span class="hljs-comment">// Generate a random 'salt'</span>
<span class="hljs-keyword">var</span> rand = Random.secure();
<span class="hljs-keyword">var</span> saltBytes = <span class="hljs-built_in">List</span>&lt;<span class="hljs-built_in">int</span>&gt;.generate(<span class="hljs-number">32</span>, (_) =&gt; _rand.nextInt(<span class="hljs-number">256</span>));
<span class="hljs-keyword">var</span> salt = base64.encode(saltBytes);
</code></pre>
<p>This generates an a list of 32 integers between 0 and 256. Afterwards we convert the list to a base64 string.</p>
<p>Let’s create a hashing function to consume this salt. Import the <code>crypto</code> package:</p>
<pre><code class="lang-dart"><span class="hljs-keyword">import</span> <span class="hljs-string">'dart:io'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'dart:convert'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'dart:math'</span>;

<span class="hljs-keyword">import</span> <span class="hljs-string">'package:mongo_dart/mongo_dart.dart'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'package:crypto/crypto.dart'</span>;

...
</code></pre>
<p>And define our hashing function outside the <code>main()</code> top-level function:</p>
<pre><code class="lang-dart">...

main() {
 ...
}

<span class="hljs-comment">// Create a hash from the given password</span>
hashPassword(<span class="hljs-built_in">String</span> password, <span class="hljs-built_in">String</span> salt) {
  <span class="hljs-keyword">var</span> codec = Utf8Codec();
  <span class="hljs-keyword">var</span> key = codec.encode(password);
  <span class="hljs-keyword">var</span> saltBytes = codec.encode(salt);
  <span class="hljs-keyword">var</span> hmacSha256 = Hmac(sha256, key);
  <span class="hljs-keyword">var</span> digest = hmacSha256.convert(saltBytes);
  <span class="hljs-keyword">return</span> digest.toString();
}
</code></pre>
<p>Let’s continue with our <code>if</code> block:</p>
<pre><code class="lang-dart"><span class="hljs-comment">// Hash the password combining the generated salt</span>
<span class="hljs-keyword">var</span> hashedPassword = hashPassword(password, salt);
</code></pre>
<p>At this point we should have a username, salt and hashed password. We can now store this in the database using the <code>users</code> reference we created earlier:</p>
<pre><code class="lang-dart"><span class="hljs-comment">// Store the username, salt and hashed password in the database</span>
<span class="hljs-keyword">await</span> users.save({
  <span class="hljs-string">'username'</span>: user,
  <span class="hljs-string">'hashedPasswd'</span>: hashedPassword,
  <span class="hljs-string">'salt'</span>: salt,
});
</code></pre>
<p>And then write to the response:</p>
<pre><code class="lang-dart">response.write(<span class="hljs-string">'Created new user'</span>);
</code></pre>
<p>And here we go:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1725975837956/8e227bae-f93a-4263-96fa-d3cb52d131d4.gif" alt class="image--center mx-auto" /></p>
<p>Take a look in your mongo database to see the new user:</p>
<pre><code class="lang-bash">$ mongo
...
...
&gt; use prod
switched to db prod
&gt; db.users.<span class="hljs-function"><span class="hljs-title">find</span></span>()
{ <span class="hljs-string">"_id"</span> : ObjectId(<span class="hljs-string">"5cf05167a7c6c9fe65683e90"</span>), <span class="hljs-string">"username"</span> : <span class="hljs-string">"Marianne"</span>, <span class="hljs-string">"hashedPasswd"</span> : <span class="hljs-string">"f7fdabbc886d7e7413e1756d52cbf473f49597e924c446cbdd12fb18b7965ae8"</span>, <span class="hljs-string">"salt"</span> : <span class="hljs-string">"Zyjut6xtbVoDurIA6RWHoCpdtmEkyE7nSJ72CsbQl34="</span> }
</code></pre>
<p>This concludes our tutorial. In the next part we will implement login and persist the session.</p>
<h2 id="heading-further-reading"><strong>Further reading</strong></h2>
<ul>
<li><p><a target="_blank" href="https://creativebracket.com/dart-and-mongodb-tutorial-1/">Dart and MongoDB Tutorial #1: Using the mongo_dart package</a></p>
</li>
<li><p><a target="_blank" href="https://creativebracket.com/write-an-http-server-in-dart/">Quick Tip: Write a HTTP server in Dart</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Dart and MongoDB Tutorial #3: Refactor our RESTful API into Controller classes]]></title><description><![CDATA[In this tutorial we will learn how to refactor our solution into a Controller class responsible to facilitating communication with our data resource.]]></description><link>https://creativebracket.hashnode.dev/dart-and-mongodb-tutorial-3</link><guid isPermaLink="true">https://creativebracket.hashnode.dev/dart-and-mongodb-tutorial-3</guid><category><![CDATA[Dart]]></category><category><![CDATA[dart programming tutorial]]></category><category><![CDATA[#dart-for-beginners]]></category><category><![CDATA[MongoDB]]></category><category><![CDATA[NoSQL]]></category><dc:creator><![CDATA[Creative Bracket Blog]]></dc:creator><pubDate>Sat, 08 Jun 2019 11:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1725971597217/50febef0-3920-4512-b8e8-af44a02b76ec.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the <a target="_blank" href="https://creativebracket.com/dart-mongo-implement-a-restful-api/">previous tutorial</a> we wrote a RESTful api to interface with a MongoDB database. In this video we will learn how to refactor our solution into a <code>PersonController</code> class responsible to facilitating communication with our data resource.</p>
<p>Classes are usually the common way of encapsulating related logic in your software. They are useful for modularising the logic you write and Dart amkes this a breeze. I hope to demonstrate this a lot more in future articles.</p>
<p>At the end of this video you will be comfortable writing classes to handle HTTP requests and return the appropriate responses. This is a common pattern used by frameworks like <a target="_blank" href="http://localhost:8080/build-web-apis-with-aqueduct-1/">Aqueduct</a> and <a target="_blank" href="https://angel-dart.dev/">Angel</a>.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/lfysc8Upa3g">https://youtu.be/lfysc8Upa3g</a></div>
<p> </p>
<p><a target="_blank" href="https://github.com/graphicbeacon/dart_mongo">Get the source code</a></p>
]]></content:encoded></item><item><title><![CDATA[Dart and MongoDB Tutorial #2: Implement a RESTful API to interface with our database]]></title><description><![CDATA[In this part we will learn how to write a RESTful api to talk to our MongoDB database using inbuilt Dart classes and the mongo_dart package.]]></description><link>https://creativebracket.hashnode.dev/dart-and-mongodb-tutorial-2</link><guid isPermaLink="true">https://creativebracket.hashnode.dev/dart-and-mongodb-tutorial-2</guid><category><![CDATA[Dart]]></category><category><![CDATA[#dart-for-beginners]]></category><category><![CDATA[MongoDB]]></category><category><![CDATA[dart programming tutorial]]></category><category><![CDATA[NoSQL]]></category><dc:creator><![CDATA[Creative Bracket Blog]]></dc:creator><pubDate>Sat, 25 May 2019 11:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1725971414271/532af3a5-59b7-442f-9717-e74e66344d24.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the <a target="_blank" href="https://creativebracket.com/dart-and-mongodb-tutorial-1/">last tutorial</a> we learnt how to talk to a MongoDB database using the mongo_dart package.</p>
<p>In this video we will learn how to write a RESTful api to talk to our MongoDB database with inbuilt Dart classes and the mongo_dart package. MongoDB is a well-known NoSQL database that stores its items as JSON documents (BSON to be exact).</p>
<p>At the end of this video, you will be comfortable writing a RESTful api to interface with a MongoDB database.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/UGuTTxH9Gfk">https://youtu.be/UGuTTxH9Gfk</a></div>
<p> </p>
<p><a target="_blank" href="https://github.com/graphicbeacon/dart_mongo">Get the source code</a></p>
]]></content:encoded></item><item><title><![CDATA[Dart and MongoDB Tutorial #1: Using the mongo_dart package]]></title><description><![CDATA[MongoDB is a well-known NoSQL database that stores its items as JSON/BSON documents. We will learn how to communicate with a MongoDB database in Dart.]]></description><link>https://creativebracket.hashnode.dev/dart-and-mongodb-tutorial-1</link><guid isPermaLink="true">https://creativebracket.hashnode.dev/dart-and-mongodb-tutorial-1</guid><category><![CDATA[Dart]]></category><category><![CDATA[dart programming tutorial]]></category><category><![CDATA[#dart-for-beginners]]></category><category><![CDATA[MongoDB]]></category><category><![CDATA[NoSQL]]></category><dc:creator><![CDATA[Creative Bracket Blog]]></dc:creator><pubDate>Tue, 07 May 2019 11:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1725970075116/524f7422-0c8d-47da-90f8-28b473dc46e0.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this video series, we will learn how to talk to a MongoDB database with Dart, using the <a target="_blank" href="https://pub.dartlang.org/packages/mongo_dart"><strong>mongo_dart</strong></a> package. MongoDB is a well-known NoSQL database that stores its items as JSON documents (BSON to be exact). At the end of this video, you will be comfortable setting up a MongoDB database, connecting to your database, creating your own collections and performing CRUD operations.</p>
<h2 id="heading-prerequisites"><strong>Prerequisites</strong></h2>
<p><a target="_blank" href="https://docs.mongodb.com/manual/administration/install-community/">Download and Install MongoDB</a> to use the database. Alternatively use the <a target="_blank" href="https://hub.docker.com/_/mongo">official docker image</a>.</p>
<p><a target="_blank" href="https://github.com/graphicbeacon/dart_mongo/tree/starter">Checkout the starter branch</a> to follow along. You will learn much better this way. I know it’s convenient just watching, but doing so will be much more fulfilling.</p>
<p>In the root directory of the project update your dependencies:</p>
<pre><code class="lang-bash">$ pub get
</code></pre>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/Y5X5rdzFScs">https://youtu.be/Y5X5rdzFScs</a></div>
<p> </p>
<h2 id="heading-setup-your-database"><strong>Setup your database</strong></h2>
<p>Run Mongo server running using the startup commands on the documentation page for your Operating System.</p>
<p>Log in to MongoDB by entering <code>mongo</code> in the terminal. Create a database and collection:</p>
<pre><code class="lang-bash">&gt; use <span class="hljs-built_in">test</span>;
switched to db <span class="hljs-built_in">test</span>
&gt; db.createCollection(<span class="hljs-string">'people'</span>);
{ <span class="hljs-string">"ok"</span> : 1 }
&gt; <span class="hljs-built_in">exit</span>
<span class="hljs-built_in">bye</span>
</code></pre>
<p>Upload the <code>people.json</code> file into the <code>people</code> collection we just created. This file is in the root project.</p>
<pre><code class="lang-bash">$ mongoimport --jsonArray -d <span class="hljs-built_in">test</span> -c people --file people.json
... connected to: localhost
... imported 100 documents
</code></pre>
<p>To confirm all is good, log in to Mongo and check the collection:</p>
<pre><code class="lang-bash">$ mongo
...
&gt; use <span class="hljs-built_in">test</span>
switched to db <span class="hljs-built_in">test</span>
&gt; show collections
people
&gt; db.people.find();
[{ <span class="hljs-string">"id"</span>: 1, <span class="hljs-string">"first_name"</span>: <span class="hljs-string">"Nolly"</span>, <span class="hljs-string">"last_name"</span>: <span class="hljs-string">"Montfort"</span>, <span class="hljs-string">"email"</span>: <span class="hljs-string">"nmontfort0@archive.org"</span>, <span class="hljs-string">"gender"</span>: <span class="hljs-string">"Male"</span>, <span class="hljs-string">"ip_address"</span>: <span class="hljs-string">"6.125.126.90"</span> },
...
...
]
</code></pre>
<p>Good job! Let’s continue with the video.</p>
<p><a target="_blank" href="https://youtu.be/Y5X5rdzFScs">Watch on YouTube</a></p>
]]></content:encoded></item><item><title><![CDATA[10 Interesting Dart and CSS libraries for May 2019]]></title><description><![CDATA[Check out these hand-picked interesting Dart packages and CSS libraries you can work with for your next web project.]]></description><link>https://creativebracket.hashnode.dev/10-interesting-dart-and-css-libraries-for-may-2019</link><guid isPermaLink="true">https://creativebracket.hashnode.dev/10-interesting-dart-and-css-libraries-for-may-2019</guid><category><![CDATA[Dart]]></category><category><![CDATA[CSS Frameworks]]></category><category><![CDATA[CSS Animation]]></category><category><![CDATA[#dart-for-beginners]]></category><dc:creator><![CDATA[Creative Bracket Blog]]></dc:creator><pubDate>Fri, 03 May 2019 11:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1725969720675/1ce4073e-cc6d-4440-bedf-cbcde7b89edf.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Dart has hit another win lately, having been listed at #12 of the <a target="_blank" href="https://insights.stackoverflow.com/survey/2019#most-loved-dreaded-and-wanted">most loved languages</a> according to the StackOverflow 2019 Annual Developer Survey. In light of that I have taken a look and hand-picked 10 of the most interesting Dart packages you can start working with along side CSS libraries you should shortlist for your next web project.</p>
<h2 id="heading-1-diohttpspubdartlangorgpackagesdio"><strong>1.</strong> <a target="_blank" href="https://pub.dartlang.org/packages/dio"><strong>dio</strong></a></h2>
<p><a target="_blank" href="https://pub.dartlang.org/packages/dio"><strong>Dio</strong></a> is a powerful library for making HTTP requests. It wraps Dart’s <code>HttpClient</code> class while extending it with support for features such as Interceptors, File Download, Request Cancellation, Timeout and several more. It can be configured globally and its super simple to use:</p>
<pre><code class="lang-dart"><span class="hljs-keyword">import</span> <span class="hljs-string">'package:dio/dio.dart'</span>;

<span class="hljs-keyword">void</span> main() <span class="hljs-keyword">async</span> {
  <span class="hljs-keyword">try</span> {
    Response res = <span class="hljs-keyword">await</span> Dio().<span class="hljs-keyword">get</span>(<span class="hljs-string">'https://news.ycombinator.com'</span>);
    <span class="hljs-built_in">print</span>(res);
  } <span class="hljs-keyword">catch</span>(e) {
    <span class="hljs-built_in">print</span>(e);
  }
}
</code></pre>
<h2 id="heading-2-bulmacsshttpsbulmaio"><strong>2.</strong> <a target="_blank" href="https://bulma.io/"><strong>BulmaCSS</strong></a></h2>
<p><a target="_blank" href="https://bulma.io/"><strong>Bulma</strong></a> is a free, open source CSS framework based on <strong>Flexbox</strong> and used by more than <strong>150,000</strong> developers, including myself. It provides helper classes for styling various UI elements while adopting a mobile-first responsive design approach. In fact I’ve worked with Bulma in <a target="_blank" href="http://localhost:8080/build-a-chat-application-in-dart-part-1/">this tutorial series</a>.</p>
<h2 id="heading-3-rxdarthttpspubdartlangorgpackagesrxdart"><strong>3.</strong> <a target="_blank" href="https://pub.dartlang.org/packages/rxdart"><strong>RxDart</strong></a></h2>
<p><a target="_blank" href="https://pub.dartlang.org/packages/rxdart"><strong>RxDart</strong></a> is a reactive functional programming library based on the ReactiveX JS counterpart. It’s one of the go-to solutions for state management in Flutter mobile apps, although it also works on server and web. RxDart builds on top of Dart’s pretty decent Streams API with extra functionality.</p>
<h2 id="heading-4-watercsshttpsgithubcomkognisewatercss"><strong>4.</strong> <a target="_blank" href="https://github.com/kognise/water.css"><strong>Water.css</strong></a></h2>
<p><a target="_blank" href="https://github.com/kognise/water.css"><strong>Water.css</strong></a> is a <em>just-add-css</em> collection of styles to make simple websites just a little nicer. It can easily be activated by sticking the CSS file in your <code>&lt;head&gt;</code> section:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://cdn.jsdelivr.net/gh/kognise/water.css@latest/dist/dark.css"</span>&gt;</span>
</code></pre>
<h2 id="heading-5-htmlhttpspubdartlangorgpackageshtml"><strong>5.</strong> <a target="_blank" href="https://pub.dartlang.org/packages/html"><strong>html</strong></a></h2>
<p><a target="_blank" href="https://pub.dartlang.org/packages/html"><strong>html</strong></a> is a pure Dart HTML5 parser. It’s a port of html5lib from Python. It’s got a straight-forward API and a useful application when <a target="_blank" href="http://localhost:8080/write-your-first-web-scraper/">writing web scrapers</a>.</p>
<h2 id="heading-6-animatecsshttpsdanedengithubioanimatecss"><strong>6.</strong> <a target="_blank" href="https://daneden.github.io/animate.css/"><strong>animate.css</strong></a></h2>
<p><a target="_blank" href="https://daneden.github.io/animate.css"><strong>Animate.css</strong></a> provides <em>just-add-water</em> CSS animations, simples! It’s got effects for bounce, pulse, shake and several more.</p>
<h2 id="heading-7-markdownhttpspubdartlangorgpackagesmarkdown"><strong>7.</strong> <a target="_blank" href="https://pub.dartlang.org/packages/markdown"><strong>markdown</strong></a></h2>
<p><a target="_blank" href="https://pub.dartlang.org/packages/markdown"><strong>markdown</strong></a> is a portable Markdown library written in Dart. It can parse Markdown into HTML on both web and server. Points for whoever can combine this with the <strong>html</strong> library. Try it out at <a target="_blank" href="https://dartlang.github.io/markdown">https://dartlang.github.io/markdown</a>.</p>
<h2 id="heading-8-dyncsshttpswwwvittoriozaccarianetdyn-css"><strong>8.</strong> <a target="_blank" href="https://www.vittoriozaccaria.net/dyn-css/"><strong>DynCSS</strong></a></h2>
<p><a target="_blank" href="https://www.vittoriozaccaria.net/dyn-css/"><strong>DynCSS</strong></a> parses your css for <code>-dyn-(attribute)</code> rules and then evaluates then via JS on browser events like <code>scroll</code> and <code>resize</code>. The result is applied to the CSS attribute you have specific in the <code>(attribute)</code> sufix. For the most part you only need to set CSS property/value pairs, but there also a JS API for custom functions, which can be accessed from Dart ??. Here’s of <a target="_blank" href="https://www.vittoriozaccaria.net/dyncss-example/">demo</a> of this at work.</p>
<h2 id="heading-9-pdfhttpspubdartlangorgpackagespdf"><strong>9.</strong> <a target="_blank" href="https://pub.dartlang.org/packages/pdf"><strong>pdf</strong></a></h2>
<p><a target="_blank" href="https://pub.dartlang.org/packages/pdf"><strong>pdf</strong></a> creates PDF files for web and Flutter projects. It can create full multi-page documents with graphics, images and text using TrueType fonts. The library provides a low-level PDF creation utility that takes care of the bits generation and a Widget system similar to Flutter’s, for easy high-level PDF creation.</p>
<p>Example code:</p>
<pre><code class="lang-dart"><span class="hljs-keyword">final</span> pdf = Document()
  ..addPage(Page(
      pageFormat: PdfPageFormat.a4,
      build: (Context context) {
        <span class="hljs-keyword">return</span> Center(
          child: Text(<span class="hljs-string">"Hello World"</span>),
        ); <span class="hljs-comment">// Center</span>
      })); <span class="hljs-comment">// Page</span>
</code></pre>
<h2 id="heading-10-hovercsshttpianlunngithubiohover"><strong>10.</strong> <a target="_blank" href="http://ianlunn.github.io/Hover/"><strong>Hover.css</strong></a></h2>
<p><a target="_blank" href="http://ianlunn.github.io/Hover/"><strong>Hover.css</strong></a> provides a collection of CSS3 powered hover effects to be applied to links, buttons, logos, SVG, featured images and so on. It can be applied to your own elements and modified too. Available in CSS, SASS and LESS.</p>
<p>And that concludes the list. Thanks for reading.</p>
<p><a target="_blank" href="https://youtube.com/c/CreativeBracket">Subscribe to my YouTube channel</a> for videos on Dart.</p>
]]></content:encoded></item><item><title><![CDATA[How to load a WebAssembly file in Dart]]></title><description><![CDATA[Learn how to load WebAssembly files in Dart for web.]]></description><link>https://creativebracket.hashnode.dev/how-to-load-a-webassembly-file-in-dart-for-web</link><guid isPermaLink="true">https://creativebracket.hashnode.dev/how-to-load-a-webassembly-file-in-dart-for-web</guid><category><![CDATA[Dart]]></category><category><![CDATA[WebAssembly]]></category><category><![CDATA[#dart language]]></category><dc:creator><![CDATA[Creative Bracket Blog]]></dc:creator><pubDate>Wed, 01 May 2019 11:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1725961441980/17e152bf-d774-47a9-a892-425a8ef8e36c.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>WebAssembly defines a binary format with an assembly-style text format for executables used by web pages. This presents a game changing opportunity for JavaScript applications to run at native speeds.</p>
<p>A question was posed by Matthew Harris on the <a target="_blank" href="https://gitter.im/dart-lang/angular">AngularDart group</a> of Gitter.im, regarding how to load a WebAssembly file in Dart. It went as follows:</p>
<blockquote>
<p><strong><em>Hey! Does anyone know how to or can link to a blog on: how to include a wasm file in dart (for web). Right now, i’m messing with JS() interop, but since wasm needs to be loaded and built first, i wondered if that’s been ported over to dart yet?</em></strong></p>
<p><strong><cite>Matthew Harris – April 27 at 22:18</cite></strong></p>
</blockquote>
<p>Since there is no official Dart documentation on the WebAssembly API, the only other option is to use the <a target="_blank" href="https://pub.dartlang.org/packages/js"><strong>js</strong></a> interop package to interface with it. To demonstrate this, I will base the solution on the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/WebAssembly/Using_the_JavaScript_API">introductory tutorial</a> on the MDN website. So let’s begin!</p>
<p><a target="_blank" href="https://gist.github.com/graphicbeacon/a2ed9b6e39a7391a893e8fe7dac25fa0">Get the source code</a></p>
<h2 id="heading-1-setup-a-dart-web-project">1. Setup a Dart web project</h2>
<p>Use the <strong>stagehand</strong> tool for this:</p>
<pre><code class="lang-bash">$ pub global activate stagehand <span class="hljs-comment"># Install if you haven't</span>
$ mkdir wa-dart &amp;&amp; <span class="hljs-built_in">cd</span> wa-dart <span class="hljs-comment"># Create your working directory</span>
$ stagehand web-simple <span class="hljs-comment"># Then run `pub get` to update dependencies</span>
</code></pre>
<p>Install the <strong>js</strong> package by updating the dependencies section of your <code>pubspec.yaml</code> file:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">dependencies:</span>
  <span class="hljs-attr">js:</span> <span class="hljs-string">^0.6.1+1</span>
</code></pre>
<p>Run <code>pub get</code> to install.</p>
<h2 id="heading-2-prepare-the-wasm-file">2. Prepare the .wasm file</h2>
<p>Go to the <code>web</code> folder of the generated project and create a <code>simple.wasm</code> file, holding the contents below:</p>
<pre><code class="lang-cpp">;; web/simple.wasm

(<span class="hljs-keyword">module</span>
  (type $t0 (func (param i32)))
  (type $t1 (func))
  (<span class="hljs-keyword">import</span> <span class="hljs-string">"imports"</span> <span class="hljs-string">"imported_func"</span> (func $imports.imported_func (type $t0)))
  (func $exported_func (type $t1)
    i32.<span class="hljs-keyword">const</span> <span class="hljs-number">42</span>
    call $imports.imported_func)
  (<span class="hljs-keyword">export</span> <span class="hljs-string">"exported_func"</span> (func $exported_func)))
</code></pre>
<p>This snippet here defines a method named <code>exported_func()</code>. This method expects to receive a method we will pass to it named <code>imported_func()</code>. It’s not compulsory to understand this file’s output entirely since you won’t be creating these from scratch anyway. You would write these in a language like C++ or Rust and compile that to the snippet you see above.</p>
<h2 id="heading-3-load-the-webassembly-file-using-the-future-api">3. Load the WebAssembly file using the Future API</h2>
<p>In the “<a target="_blank" href="https://developer.mozilla.org/en-US/docs/WebAssembly/Using_the_JavaScript_API#Loading_our_wasm_module_without_streaming">Loading our wasm file without streaming</a>” example on MDN, the <code>fetch()</code> method was used to load the <code>.wasm</code> file as an <code>ArrayBuffer</code> and passed as the input to the <code>WebAssembly.initiate()</code> method.</p>
<p>In <code>web/main.dart</code> let’s perform a HTTP request to retrieve our <code>.wasm</code> file as an <code>ArrayBuffer</code>:</p>
<pre><code class="lang-dart"><span class="hljs-keyword">import</span> <span class="hljs-string">'dart:html'</span>;

<span class="hljs-keyword">void</span> main() <span class="hljs-keyword">async</span> {
  <span class="hljs-keyword">var</span> request = <span class="hljs-keyword">await</span> HttpRequest.request(
    <span class="hljs-string">'./simple.wasm'</span>,
    responseType: <span class="hljs-string">'arraybuffer'</span>,
    mimeType: <span class="hljs-string">'application/wasm'</span>,
  );

  <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> Initiate WA with response</span>
}
</code></pre>
<p>The <code>responseType</code> and <code>mimeType</code> named arguments are set to the appropriate values to get the expected <code>ArrayBuffer</code>response.</p>
<h2 id="heading-4-initiate-the-webassembly-instructions"><strong>4. Initiate the WebAssembly instructions</strong></h2>
<p>Let’s create an interop file to interface with the WebAssembly API. Create a <code>web/wa_interop.dart</code> file with these contents:</p>
<pre><code class="lang-dart"><span class="hljs-meta">@JS</span>(<span class="hljs-string">'WebAssembly'</span>)
<span class="hljs-keyword">library</span> wa_interop;

<span class="hljs-keyword">import</span> <span class="hljs-string">'package:js/js.dart'</span>; <span class="hljs-comment">// contains the `@JS()` annotation</span>
<span class="hljs-keyword">import</span> <span class="hljs-string">'package:js/js_util.dart'</span>; <span class="hljs-comment">// contains needed util methods</span>
</code></pre>
<p>The first line sets the context for the JS interop by setting the <code>'WebAssembly'</code> argument for the <code>@JS()</code> annotation. A library name is required for every interop file created. <em>Look at the further reading materials below for a much detailed article on JS interop. For now let’s resume.</em></p>
<p>Add the interop logic for the <code>initiate()</code> method:</p>
<pre><code class="lang-dart"><span class="hljs-meta">@JS</span>()
<span class="hljs-keyword">external</span> instantiate(<span class="hljs-built_in">dynamic</span> bytes, <span class="hljs-built_in">dynamic</span> importObj);
</code></pre>
<p>The first parameter of our <code>initiate()</code> method is the list of bytes from the <code>.wasm</code> file while the second is an object containing configuration information that is passed into the loaded <code>.wasm</code> file. The example on MDN looks like this:</p>
<pre><code class="lang-dart">{
  imports: {
    imported_func: (args) =&gt; <span class="hljs-built_in">window</span>.console.log(args),
  }
}
</code></pre>
<p>The snippet contains the <code>imported_func</code> method expected by the WebAssembly file.</p>
<p>Return to <code>web/main.dart</code> replace the <code>// TODO: Initiate WA with response</code> line with the call to <code>initiate()</code>:</p>
<pre><code class="lang-dart"><span class="hljs-keyword">var</span> wa = <span class="hljs-keyword">await</span> instantiate(
  request.response,
  {
    <span class="hljs-string">'imports'</span>: {
      <span class="hljs-string">'imported_func'</span>: (args) =&gt; <span class="hljs-built_in">window</span>.console.log(args),
    }
  }
);

<span class="hljs-built_in">window</span>.console.log(results);
</code></pre>
<p>The second argument contains the configuration object we passed through. In this case we have passed in a <code>Map&lt;String, dynamic&gt;</code> type. This however won’t run the way we expect it to, but we’ll fix that soon.</p>
<p>Open the terminal and run our local server:</p>
<pre><code class="lang-bash">$ webdev serve --hot-reload
</code></pre>
<p>Visiting <a target="_blank" href="http://localhost:8080"><code>http://localhost:8080</code></a> in the browser will throw this error in the console:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1725960925002/fa213a46-df2d-484a-a064-0a0124c694d0.png" alt class="image--center mx-auto" /></p>
<p>This is simply because Dart <code>Map&lt;String, dynamic&gt;</code> types are opaque in JavaScript. They don’t translate to native JS objects!</p>
<p>To resolve this we’ll use some utility methods to build a native JS object from our Map. These are <code>newObject()</code> which creates a native JavaScript object, and <code>setProperty()</code> which allow us to set a property with a value, providing the JS object in which to perform this mutation.</p>
<p>In <code>web/wa_interop.dart</code> let’s define this top-level function that’ll use those methods:</p>
<pre><code class="lang-dart">jsObj(<span class="hljs-built_in">Map</span>&lt;<span class="hljs-built_in">String</span>, <span class="hljs-built_in">dynamic</span>&gt; dartMap) {
  <span class="hljs-keyword">var</span> jsObject = newObject(); <span class="hljs-comment">// Define our JS object</span>

  dartMap.forEach((name, value) {
    setProperty(jsObject, name, value); <span class="hljs-comment">// Add the name/value pairs from our `dartMap` variable</span>
  });

  <span class="hljs-keyword">return</span> jsObject; <span class="hljs-comment">// Return the native JS object</span>
}
</code></pre>
<p>Return to <code>web/main.dart</code> and wrap the configuration object as such:</p>
<pre><code class="lang-dart">jsObj({
  <span class="hljs-string">'imports'</span>: jsObj({
    <span class="hljs-string">'imported_func'</span>: (args) =&gt; <span class="hljs-built_in">window</span>.console.log(args),
  })
});
</code></pre>
<p>This should log out a resolved <code>Promise</code> object. Since the Promise has been resolved, we cannot <code>await</code> for it this time. We have to use <code>.then()</code> to process the results.</p>
<pre><code class="lang-dart">wa.then((results) {
  <span class="hljs-built_in">window</span>.console.log(results);
  <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> Extract `exported_func` from compiled .wasm file</span>
});
</code></pre>
<p>Logging out <code>results</code> displays the following output:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1725960990977/9eac64f5-4630-41b3-ae86-dc7cfcc8d48a.png" alt class="image--center mx-auto" /></p>
<p>What we care about is the <code>exported_func</code> prop from the <code>.wasm</code> file. To invoke this method let’s use the <code>getProperty()</code> method to retrieve our export:</p>
<pre><code class="lang-dart">wa.then((results) {
  <span class="hljs-keyword">var</span> exportsObj = getProperty(results.instance, <span class="hljs-string">'exports'</span>);
  <span class="hljs-built_in">Function</span> exportedFn = getProperty(exportsObj, <span class="hljs-string">'exported_func'</span>);
  exportedFn(); <span class="hljs-comment">// Logs `42` to the console</span>
});
</code></pre>
<p>This should now log <code>42</code> to the console. If that’s the case then we’re done!</p>
<h2 id="heading-bundling-for-production"><strong>Bundling for production</strong></h2>
<p>When building for production, use the <code>--no-release</code> flag. This uses the <code>dartdevc</code> tool to compile instead of <code>dart2js</code>. In other words this supports modern browsers running ES6.</p>
<p><strong>EDIT:</strong> After further investigation, you can bundle to a working ES5 output. In <code>web/wa_interop.dart</code>, add an interop class for the JavaScript <code>Promise</code> API:</p>
<pre><code class="lang-dart"><span class="hljs-meta">@JS</span>()
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Promise</span> </span>{
  <span class="hljs-keyword">external</span> then(<span class="hljs-built_in">Function</span> callback);
}
</code></pre>
<p>In <code>web/main.dart</code> set the return type of the instantiate call:</p>
<pre><code class="lang-dart">Promise wa = <span class="hljs-keyword">await</span> instantiate( <span class="hljs-comment">// Replaced `var` with `Promise`</span>
  ...
</code></pre>
<p>We need to wrap the functions we are passing using the <code>allowInterop()</code> top-level method from the <strong>js</strong> package utility:</p>
<pre><code class="lang-dart"><span class="hljs-string">'imported_func'</span>: allowInterop((args) =&gt; <span class="hljs-built_in">window</span>.console.log(args)),
</code></pre>
<p>The last thing we need to do is to adjust the callback implementation for the instantiate promise result:</p>
<pre><code class="lang-dart">wa.then(allowInterop((result) {
  <span class="hljs-keyword">var</span> instance = getProperty(result, <span class="hljs-string">'instance'</span>);
  <span class="hljs-keyword">var</span> exportsObj = getProperty(instance, <span class="hljs-string">'exports'</span>);
  <span class="hljs-built_in">Function</span> exportedFn = getProperty(exportsObj, <span class="hljs-string">'exported_func'</span>);

  exportedFn();
}));
</code></pre>
<p>Alright. So that’s it for enabling support in the ES5 output.</p>
<p><a target="_blank" href="https://gist.github.com/graphicbeacon/a2ed9b6e39a7391a893e8fe7dac25fa0">Get the source code</a></p>
<h2 id="heading-further-reading"><strong>Further reading</strong></h2>
<ul>
<li><p><a target="_blank" href="https://pub.dartlang.org/packages/js"><strong>js</strong> package on Pub</a></p>
</li>
<li><p><a target="_blank" href="https://creativebracket.com/how-to-use-javascript-libraries-in-your-dart-applications/">How to use JavaScript libraries in your Dart applications</a></p>
</li>
<li><p><a target="_blank" href="https://developer.mozilla.org/en-US/docs/WebAssembly/Using_the_JavaScript_API">Using the WebAssembly JavaScript API</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[AngularDart Tutorial #6: Firebase Integration Complete]]></title><description><![CDATA[We will continue the Firebase Dart package integration, using the Bootstrap UI library to build our user interface.]]></description><link>https://creativebracket.hashnode.dev/angulardart-tutorial-lets-build-a-bookmark-manager-firebase-integration-2</link><guid isPermaLink="true">https://creativebracket.hashnode.dev/angulardart-tutorial-lets-build-a-bookmark-manager-firebase-integration-2</guid><category><![CDATA[Dart]]></category><category><![CDATA[#dart-for-beginners]]></category><category><![CDATA[dart programming tutorial]]></category><category><![CDATA[Firebase]]></category><category><![CDATA[angulardart]]></category><dc:creator><![CDATA[Creative Bracket Blog]]></dc:creator><pubDate>Tue, 30 Apr 2019 11:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1725960473604/994c4d4d-d66e-4417-afe8-b6cdb6f1922f.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the <a target="_blank" href="https://creativebracket.com/angulardart-tutorial-lets-build-a-bookmark-manager-firebase-integration/">previous tutorial</a> we began integrating Firebase as our database for persisting our bookmark entries. In this AngularDart tutorial, we will continue to use the Firebase Dart package to interact with our online database. We will continue to use the Bootstrap UI library to build our user interface.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/_3mm253K7rU">https://youtu.be/_3mm253K7rU</a></div>
<p> </p>
<h2 id="heading-further-reading"><strong>Further reading</strong></h2>
<ol>
<li><p><a target="_blank" href="https://webdev.dartlang.org/angular/guide"><strong>AngularDart Guide</strong></a></p>
</li>
<li><p><a target="_blank" href="https://firebase.google.com/docs/database"><strong>Firebase Realtime Database Guide</strong></a></p>
</li>
<li><p><a target="_blank" href="https://egghead.io/courses/get-started-wtih-dart"><strong>Get started with Dart</strong></a> <a target="_blank" href="http://egghead.io/"><strong>Egghead.io course</strong></a></p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[AngularDart Tutorial #5: Firebase Integration]]></title><description><![CDATA[We will learn how to integrate Firebase as our database for persisting our bookmark entries.]]></description><link>https://creativebracket.hashnode.dev/angulardart-tutorial-lets-build-a-bookmark-manager-firebase-integration</link><guid isPermaLink="true">https://creativebracket.hashnode.dev/angulardart-tutorial-lets-build-a-bookmark-manager-firebase-integration</guid><category><![CDATA[Dart]]></category><category><![CDATA[#dart-for-beginners]]></category><category><![CDATA[dart programming tutorial]]></category><category><![CDATA[Firebase]]></category><category><![CDATA[angulardart]]></category><dc:creator><![CDATA[Creative Bracket Blog]]></dc:creator><pubDate>Thu, 25 Apr 2019 11:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1725960132651/41d7b979-724b-4791-8de1-895a145f5dc7.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the <a target="_blank" href="https://creativebracket.com/angulardart-tutorial-lets-build-a-bookmark-manager-4/">previous tutorial</a> we implemented basic form validation using the <code>NgForm</code> directive with its <code>NgControl</code> counterpart. In this video we will learn how to integrate Firebase as our database for persisting our bookmark entries.</p>
<p>We will create a new project in our Firebase console and use the Firebase Dart package to interact with our online database. We will continue to use the Bootstrap UI library to build our user interface.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/JgQRy6g79l4">https://youtu.be/JgQRy6g79l4</a></div>
<p> </p>
<p><a target="_blank" href="https://youtu.be/JgQRy6g79l4">Watch on YouTube</a></p>
<p><a target="_blank" href="https://github.com/graphicbeacon/angulardart-bookmark-manager">Get the source code</a></p>
<h2 id="heading-further-reading"><strong>Further reading</strong></h2>
<ol>
<li><p><a target="_blank" href="https://webdev.dartlang.org/angular/guide"><strong>AngularDart Guide</strong></a></p>
</li>
<li><p><a target="_blank" href="https://firebase.google.com/docs/database">Firebase Realtime Database Guide</a></p>
</li>
<li><p><a target="_blank" href="https://egghead.io/courses/get-started-wtih-dart"><strong>Get started with Dart</strong></a> <a target="_blank" href="http://egghead.io/"><strong>Egghead.io course</strong></a></p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[AngularDart Tutorial #4: Forms and Validation]]></title><description><![CDATA[In the previous tutorial we refactored our form functionality into a separate component. We will learn how to implement validation for the form.]]></description><link>https://creativebracket.hashnode.dev/angulardart-tutorial-lets-build-a-bookmark-manager-4</link><guid isPermaLink="true">https://creativebracket.hashnode.dev/angulardart-tutorial-lets-build-a-bookmark-manager-4</guid><category><![CDATA[Dart]]></category><category><![CDATA[#dart-for-beginners]]></category><category><![CDATA[dart programming tutorial]]></category><category><![CDATA[angulardart]]></category><dc:creator><![CDATA[Creative Bracket Blog]]></dc:creator><pubDate>Thu, 11 Apr 2019 11:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1725927927977/ddc276db-9e7f-46b1-88a2-02a1217ca23f.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the <a target="_blank" href="https://creativebracket.com/angulardart-tutorial-lets-build-a-bookmark-manager-3/">previous video</a>, we refactored our form functionality into a separate component, using the special annotations to bind custom attributes and define custom events.</p>
<p>In this part you will learn how to implement validation for the form, utilising the <strong>NgForm</strong> directive and its <strong>NgControl</strong> counterpart. We will continue to use the Bootstrap UI library to build our user interface.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/RtaHYIPKdig">https://youtu.be/RtaHYIPKdig</a></div>
<p> </p>
<p><a target="_blank" href="https://youtu.be/RtaHYIPKdig">Watch on YouTube</a></p>
<p><a target="_blank" href="https://github.com/graphicbeacon/angulardart-bookmark-manager/tree/part-4">Get the source code</a></p>
<h2 id="heading-further-reading"><strong>Further reading</strong></h2>
<ol>
<li><p><a target="_blank" href="https://webdev.dartlang.org/angular/guide"><strong>AngularDart Guide</strong></a></p>
</li>
<li><p><a target="_blank" href="http://localhost:8080/generate-the-scaffolding-for-your-next-project/">Auto-Generate the scaffolding for your next project</a></p>
</li>
<li><p><a target="_blank" href="https://egghead.io/courses/get-started-wtih-dart"><strong>Get started with Dart</strong> Egghead.io course</a></p>
</li>
</ol>
]]></content:encoded></item></channel></rss>