<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Moses Karunia</title>
    <description>The latest articles on DEV Community by Moses Karunia (@moseskarunia).</description>
    <link>https://dev.to/moseskarunia</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F190916%2F9a11c039-4d27-41fb-bcd5-6091f0eeb856.jpeg</url>
      <title>DEV Community: Moses Karunia</title>
      <link>https://dev.to/moseskarunia</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/moseskarunia"/>
    <language>en</language>
    <item>
      <title>Simply Responsive</title>
      <dc:creator>Moses Karunia</dc:creator>
      <pubDate>Tue, 08 Dec 2020 15:58:47 +0000</pubDate>
      <link>https://dev.to/moseskarunia/simply-responsive-476k</link>
      <guid>https://dev.to/moseskarunia/simply-responsive-476k</guid>
      <description>&lt;p&gt;Hello guys, so I just published my first open source library for flutter.&lt;/p&gt;

&lt;p&gt;This is a mobile-first widget to help us build a responsive app across mobile, tablet, and desktop with ease. Unlike the CSS 12 grid system, The design of simply_responsive is based on 3-columns design of a desktop website. This has an advantage of being simpler to use than the CSS 12 grid system, at the cost of reduced possible flexibilities. I try to make this library as tested as possible.&lt;/p&gt;

&lt;p&gt;And, since it's responsive, it'll be no need for you to lock the orientation of your app to portrait only!&lt;/p&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;SimplyResponsiveBody&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;LayoutConfig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MediaQuery&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nl"&gt;leftChild:&lt;/span&gt; &lt;span class="n"&gt;ListView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Home'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Profile'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Sign Out'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nl"&gt;centerChild:&lt;/span&gt; &lt;span class="n"&gt;ListView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Lorem Ipsum'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Lorem ipsum dolor sit amet'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nl"&gt;rightChild:&lt;/span&gt; &lt;span class="n"&gt;ListView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Tap to like'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Tap to dislike'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just by writing that code, you can make it responsive across screen sizes and orientation.&lt;/p&gt;

&lt;p&gt;Basically, the centerChild is the widget which will appears everytime (although not required).&lt;/p&gt;

&lt;p&gt;The left column is usually used to display navigational menus. On this early release, the widget will just hide the left column if the screen is not enough (usually in mobile portrait). You should put it in the drawer if that's the case.&lt;/p&gt;

&lt;p&gt;The right column is usually used to display additional content (Like Editor Basics on DEV). On this early release, the widget will just hide the right column if the screen is not enough (usually in mobile portrait and tablet if left column is visible). You should put it in the endDrawer if that's the case.&lt;/p&gt;

&lt;p&gt;There's also a two-column mode if you pass centerFlex to 0, and set the centerChild to null.&lt;/p&gt;




&lt;p&gt;Feel free to ask any question and give any criticism and suggestion! Thank you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pub.dev/packages/simply_responsive"&gt;https://pub.dev/packages/simply_responsive&lt;/a&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
    </item>
    <item>
      <title>Introduction to Simply Responsive Design</title>
      <dc:creator>Moses Karunia</dc:creator>
      <pubDate>Fri, 27 Nov 2020 11:31:35 +0000</pubDate>
      <link>https://dev.to/moseskarunia/introduction-to-simply-responsive-design-4lb6</link>
      <guid>https://dev.to/moseskarunia/introduction-to-simply-responsive-design-4lb6</guid>
      <description>&lt;p&gt;There are a lot of device screen sizes right now. While it's mostly a good thing to give users options, we, as developer (and designer) often suffers (lol) because we need to support those different screen sizes.&lt;/p&gt;

&lt;p&gt;There is a popular choice in the 12 grid system in the web development world. But in the app development world, 12 grid responsive system also not that popular (wonder why).&lt;/p&gt;

&lt;p&gt;The example of this is the iphone and ipad app. There are quite a lot "ipad" apps out there when downloaded, only displays the layout in the cropped "iphone" view, which is sucks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Enter the Simply Responsive Design.
&lt;/h3&gt;

&lt;p&gt;Simply Responsive Design is a term I coined (what a creative name right?) myself. This design system derives / inspired from Material Design mostly, and I build it in the context of me, as a flutter developer.&lt;/p&gt;

&lt;p&gt;Unlike the 12 grid system, a Simply Responsive Design (or SRD), only assumes there are 3 maximum columns on the screen, along with fixed top and bottom bar / app bar. This simplification has both advantage and disadvantage. Basically, SRD trades flexibility for development speed.&lt;/p&gt;

&lt;p&gt;SRD has 3 kind of screen sizes in mind:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Mobile (&amp;lt; 600px width)&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JlNlfhMD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ac3m6jg8qp4sld7v7dkb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JlNlfhMD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ac3m6jg8qp4sld7v7dkb.jpg" alt="SRD Mobile" width="880" height="578"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tablet (600 - 767px width)&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Lngr-vx2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/s60t5fug9if4r6gkvdnu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Lngr-vx2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/s60t5fug9if4r6gkvdnu.jpg" alt="SRD Tablet" width="880" height="372"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Desktop (&amp;gt;= 768px width)&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3WOG6FjD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/k44vepyzcfscbtxkw9m4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3WOG6FjD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/k44vepyzcfscbtxkw9m4.jpg" alt="SRD Desktop" width="880" height="298"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As you can see, the UI (or widgets in flutter) placements, are kinda predictable across screen sizes. This makes your development speed faster and easy, if in the beginning of a project, you already make a custom scaffold to abstract out the logic. This way, it will be much easier for subsequent codes to be responsive out of the box.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/// Prototype of SRD as an abstracted out flutter widget
return SimplyResponsiveScaffold(
  title: 'MyTitle'
  leftContents: &amp;lt;Widget&amp;gt;[],
  centerContents: &amp;lt;Widget&amp;gt;[],
  rightContents: &amp;lt;Widget&amp;gt;[],
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With that widget, no matter what screen size your app is running on, The &lt;code&gt;SimplyResponsiveScaffold&lt;/code&gt; will automatically determines where your left, or center, or right should be placed based on the screen size.&lt;/p&gt;

&lt;p&gt;(This also make your app works automatically when rotated)&lt;/p&gt;

&lt;p&gt;=====&lt;/p&gt;

&lt;p&gt;That's it for the introduction part of Simply Responsive Design. In the future articles, I'm going add in-depth explanation of UI elements interactions SRD. I also plan to write a custom flutter library to make it easier to implement SRD.&lt;/p&gt;

&lt;p&gt;Thank you and see you in the next article!&lt;/p&gt;

</description>
      <category>ux</category>
      <category>design</category>
      <category>flutter</category>
    </item>
    <item>
      <title>Fixing Flutter iOS build fail</title>
      <dc:creator>Moses Karunia</dc:creator>
      <pubDate>Sun, 16 Aug 2020 19:26:37 +0000</pubDate>
      <link>https://dev.to/moseskarunia/fixing-flutter-ios-build-fail-2mcm</link>
      <guid>https://dev.to/moseskarunia/fixing-flutter-ios-build-fail-2mcm</guid>
      <description>&lt;p&gt;I have sour experiences on configuring your iOS Flutter build, since I have no experience whatsoever in iOS. But after reading some articles on the internet, I found that many iOS devs also think iOS deployment is kinda hard to do. Often I did shadow punching on google before finding random stranger post a nice pointer.&lt;/p&gt;

&lt;p&gt;This article mainly meant as reference in case someone (or myself in the future), hit some roadblock in order to make one. Most credits also go to guys who originally post these solutions I found on the internet. I cannot add any reference to you, because it lost in my search history. You can comment below if you want to be mentioned, though.&lt;/p&gt;

&lt;p&gt;Please note that most problem can be solved by creating a new flutter project using the latest stable version, copy-pasting the content of &lt;code&gt;iOS/&lt;/code&gt;, and applying manually-made changes (like adding permission on info.plist, firebase-related adjustments, etc)&lt;/p&gt;

&lt;p&gt;I'll try to keep this article updated in future Flutter, iOS &amp;amp; XCode releases.&lt;/p&gt;

&lt;p&gt;Works well on:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;MacOS Catalina 10.15.6&lt;br&gt;
Flutter 1.20.2&lt;br&gt;
Dart 2.7.0&lt;br&gt;
XCode 11.6&lt;br&gt;
iPadOS 13.6.1 (iPad 10.2 - 2019)&lt;br&gt;
iOS Deployment 9.0 (The one set in &lt;code&gt;ios/Podfile&lt;/code&gt; as &lt;code&gt;platform :ios, '9.0'&lt;/code&gt;)&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Use the latest STABLE release
&lt;/h3&gt;

&lt;p&gt;Why? Because, it's nice if you can shave down your potential problems by using stable releases. &lt;/p&gt;

&lt;p&gt;e.g. XCode version, iPadOS / iOS version, flutter version etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  Frameworks, Libraries and Embedded Content
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--D5rz5SSb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ah3ixg983mpht40zkami.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--D5rz5SSb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ah3ixg983mpht40zkami.png" alt="Alt Text" width="880" height="192"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  iOS Project Structure
&lt;/h3&gt;

&lt;p&gt;Pay attention on the content under &lt;code&gt;Flutter/&lt;/code&gt; and &lt;code&gt;Runner/&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jen__ynD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wleb9hvnid60eevdzdf8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jen__ynD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wleb9hvnid60eevdzdf8.png" alt="Alt Text" width="540" height="860"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Targets &amp;gt; Runner &amp;gt; Build Phases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Run Script
&lt;/h3&gt;

&lt;p&gt;The content should EXACTLY be&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/bin/sh "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" build
/bin/sh "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" embed

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

&lt;/div&gt;



&lt;p&gt;With ONLY "Show environment variables in build log" checked.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compile Sources, Link binary with libraries, Copy Bundle Resources and Embed Frameworks
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sJwxiS2e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5nf54uxdm7d8xmqz7w4y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sJwxiS2e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5nf54uxdm7d8xmqz7w4y.png" alt="Alt Text" width="880" height="880"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Thin Library
&lt;/h3&gt;

&lt;p&gt;Content should EXACTLY be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/bin/sh "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" embed
/bin/sh "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" thin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(NOT &lt;code&gt;embed_and_thin&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;With ONLY "Show environment variables in build log" checked.&lt;/p&gt;

&lt;h2&gt;
  
  
  Targets &amp;gt; Runner &amp;gt; Build Settings
&lt;/h2&gt;

&lt;h3&gt;
  
  
  All &amp;gt; Linking &amp;gt; Other Linker Flags
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9g5uXjVw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/viqw30s2jq15yaaxnar5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9g5uXjVw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/viqw30s2jq15yaaxnar5.png" alt="Alt Text" width="880" height="322"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;This is the snippet of my package.yaml if you are wondering (because sometimes build fails because of certain release of a library in your dependency)&lt;/p&gt;

&lt;p&gt;Note that I didn't use any &lt;code&gt;^&lt;/code&gt; to prefix the version to make things more certain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;environment:
  sdk: "&amp;gt;=2.7.0 &amp;lt;3.0.0"
  flutter: 1.20.2

dependencies:
  flutter:
    sdk: flutter

  material_design_icons_flutter: 4.0.5345
  cupertino_icons: 0.1.3
  google_fonts: 0.3.2
  get_it: 4.0.2
  equatable: 1.2.0
  dartz: 0.9.1
  meta: 1.1.8
  json_annotation: 3.0.1
  google_sign_in: 4.5.1
  sign_in_with_apple: 
  firebase_core: 0.4.4
  firebase_auth: 0.15.4
  firebase_messaging: 6.0.16
  firebase_analytics: 5.0.16
  graphql: 3.0.2
  flutter_bloc: 6.0.1
  qr_flutter: 3.2.0
  jaguar_jwt: 2.1.6
  barcode_scan: 3.0.1
  dio: 3.0.9
  image_cropper: 1.2.3
  image_picker: 0.6.7+4
  intl: 0.16.1
  stream_transform: 1.2.0
  flare_flutter: 2.0.3
  flutter_svg: 0.18.0
  shared_preferences: 0.5.7+3
  collection: 1.14.13
  flutter_local_notifications: 1.4.4+2
  pattern_formatter: 1.0.2
  hydrated_bloc: 6.0.1
  url_launcher: 5.5.0
  pull_to_refresh: 1.6.0
  copy_with_extension: "&amp;gt;=1.2.0 &amp;lt;2.0.0"
  flame: 0.24.0
  flutter_i18n: 0.17.0
  flutter_neumorphic: 3.0.1
  package_info: 0.4.1
  extended_image: 1.1.0

dev_dependencies:
  flutter_test:
    sdk: flutter
  mockito: 4.1.1
  build_runner: 1.10.1
  json_serializable: 3.3.0
  bloc_test: 7.0.0
  copy_with_extension_gen: "&amp;gt;=1.2.0 &amp;lt;2.0.0"
  flutter_launcher_icons: 0.7.5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;That's all I think are important, if you wanna know any other configs, feel free to lemme know in the comment. I'll let you know if I know the answer.&lt;/p&gt;

&lt;p&gt;Hope this saves your time!&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>troubleshooting</category>
      <category>ios</category>
    </item>
    <item>
      <title>Managing deeply-nested Flutter files</title>
      <dc:creator>Moses Karunia</dc:creator>
      <pubDate>Fri, 07 Aug 2020 07:26:47 +0000</pubDate>
      <link>https://dev.to/moseskarunia/managing-deeply-nested-flutter-files-25dd</link>
      <guid>https://dev.to/moseskarunia/managing-deeply-nested-flutter-files-25dd</guid>
      <description>&lt;p&gt;One of many common problems a Flutter developer might face is that their widget files are easy to get crazily deeply-nested. This pose a problem because a deeply nested widgets are relatively harder to read.&lt;/p&gt;

&lt;p&gt;One of the solution is to break it into separate, smaller chunk of widget. This way, you can maximize readability by containerizing each widget based on its functionality.&lt;/p&gt;

&lt;p&gt;That's a good solution, but for me it's not optimal, because now, there are a lot of separate one-use widgets scattered in our project folder. One of the problem is it makes my naming harder, and it clutters my VS Code autocomplete.&lt;/p&gt;

&lt;p&gt;So, it'll be better if we can break our deeply-nested widget file, without it clutters our IDE / editor autocomplete.&lt;/p&gt;

&lt;p&gt;This is where I used &lt;code&gt;part&lt;/code&gt; and &lt;code&gt;part of&lt;/code&gt; directive.&lt;/p&gt;

&lt;p&gt;This is an example of how I structure my files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;File: lib/widgets/my_widget/my_widget.dart

/// Import declarations

part 'my_top_widget.w.dart';
part 'my_center_widget.w.dart';
part 'my_bottom_widget.w.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build (BuildContext context) {
    return Scaffold (
      body: LayoutBuilder(
        build: (context, boxConstraints) {
          return ListView(
            children: &amp;lt;Widget&amp;gt; [
              _$MyFirstSubwidget();
              _$MySecondSubwidget();
            ],
          );
        }
      );
    );
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;File: lib/widgets/my_widget/my_first_widget.w.dart

/// A "Part of" file cannot have its own import declarations

part of 'my_widget.dart';

class _$MyFirstWidget extends StatelessWidget {
  @override
  Widget build (BuildContext context) {
    // TODO: Return widget
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;File: lib/widgets/my_widget/my_second_widget.w.dart

/// A "Part of" file cannot have its own import declarations

part of 'my_widget.dart';

class _$MySecondWidget extends StatelessWidget {
  @override
  Widget build (BuildContext context) {
    // TODO: Return widget
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here are the steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Put the complex widget into its own folder (my_widget/my_widget.dart)&lt;/li&gt;
&lt;li&gt;Prefixing the sub-widgets name with &lt;code&gt;_$&lt;/code&gt; (You don't need the dollar &lt;code&gt;$&lt;/code&gt; sign. It's just my way to differ it with a class-level private. The key is to make it private with &lt;code&gt;_&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Postfix sub-widget file name with &lt;code&gt;*.w.dart&lt;/code&gt;. It's just my personal convention to say that a widget is a sub-widget of another widget.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I would also like to add, that by postfixing your sub-widget files with &lt;code&gt;*.w.dart&lt;/code&gt;, you can also make similar separate file for your helper function with &lt;code&gt;*.u.dart&lt;/code&gt;, where u stands for utility. Again, you can choose whatever postfix you like.&lt;/p&gt;

&lt;p&gt;Bonus advantage is, by using this approach, you can easily move the sub-widget out of the folder in case you need it to use it in another main widget. (Too many early refactors are not good)&lt;/p&gt;

&lt;p&gt;Hope this tip helps you make flutter files more readable.&lt;/p&gt;

&lt;p&gt;Cheers!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.freepik.com/vectors/building"&gt;Cover image provided by &lt;/a&gt;&lt;a href="http://www.freepik.com"&gt;www.freepik.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>codequality</category>
    </item>
    <item>
      <title>Enum in typescript</title>
      <dc:creator>Moses Karunia</dc:creator>
      <pubDate>Thu, 31 Oct 2019 12:25:56 +0000</pubDate>
      <link>https://dev.to/moseskarunia/enum-in-typescript-146l</link>
      <guid>https://dev.to/moseskarunia/enum-in-typescript-146l</guid>
      <description>&lt;p&gt;Changelog:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;6 Nov 2019: Added &lt;code&gt;type&lt;/code&gt; for better developer experience.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;I know we can use typescript's &lt;code&gt;enum&lt;/code&gt;, but, the difficulty arises when I'm receiving string in REST, and want to validate the property value in the request.&lt;/p&gt;

&lt;p&gt;This is the way I write my enums:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// ===== DECLARATION =====

type TerrainEnum = 'MEADOW' | 'OCEAN' | 'FOREST';

class Terrain {
  public static readonly Meadow = 'MEADOW';
  public static readonly Ocean = 'OCEAN';
  public static readonly Forest = 'FOREST';

  public static isValid = (value: string): boolean =&amp;gt; (
    value === Terrain.Meadow ||
    value === Terrain.Ocean ||
    value === Terrain.Forest
  );
}

// ===== USAGE =====

// Validate
Terrain.isValid(value);

// In function parameter
const myFunction = (terrain: TerrainEnum): void =&amp;gt; {}

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

&lt;/div&gt;



&lt;p&gt;I think this way you have a built-in input validations, simply by calling &lt;code&gt;isValid()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I'm interested in what you guys think. Maybe we can find any better option out there.&lt;/p&gt;

&lt;p&gt;So, what's your preferred way to write enums? And what's the reason behind yours?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Write cleaner function's optional parameters</title>
      <dc:creator>Moses Karunia</dc:creator>
      <pubDate>Tue, 29 Oct 2019 06:08:41 +0000</pubDate>
      <link>https://dev.to/moseskarunia/write-cleaner-function-s-optional-parameters-1nei</link>
      <guid>https://dev.to/moseskarunia/write-cleaner-function-s-optional-parameters-1nei</guid>
      <description>&lt;p&gt;&lt;em&gt;Clean all the codes!&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Update: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Code typo fixed.&lt;/li&gt;
&lt;li&gt;Adding default value to optional to make it easier to destructure.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;Normally, we can put the optionals last in our function declaration. This way we can simply omit it from our calls when we don't need it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Declaration
const myFunction = (param1: string, param2: number, param3?: string, param4?: number) { }

// Call
myFunction("Call me maybe", 12345);

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

&lt;/div&gt;



&lt;p&gt;But, there's a time where we need to assign &lt;code&gt;param4&lt;/code&gt; without &lt;code&gt;param3&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;myFunction("Call me maybe", 12345, undefined, 67890);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I think that's messy, because we are forced to write &lt;code&gt;undefined&lt;/code&gt; first. This is getting incrementally annoying if there're more than 1 &lt;code&gt;undefined&lt;/code&gt; in-between. (especially if you are a bit OCD like me)&lt;/p&gt;

&lt;p&gt;So, I then remember how the flutter team handles optional parameters, and I think it makes my typescript code much cleaner.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Declaration
const myFunction = (param1: string, param2: number, 
  optionals: { param3?: string, param4?: number } = { }) { }

// Call 1
myFunction("Call me maybe", 12345, { param4: 67890 });

// Call 2
myFunction("Call me maybe", 12345);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And to make things better, we can destructure our optionals first, instead of prefixing everything with &lt;code&gt;optionals.&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const myFunction = (param1: string, param2: number, 
  optionals: { param3?: string, param4?: number } = { }) { 
  const { param3, param4 } = optionals;

  // Write any code here
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;&lt;strong&gt;UPDATE:&lt;/strong&gt; I changed the optionals declaration from &lt;code&gt;optionals?: {}&lt;/code&gt; to &lt;code&gt;optionals: {} = {}&lt;/code&gt;. This way, you can safely destructure &lt;code&gt;optionals&lt;/code&gt; even if it's undefined, because it will be replaced with empty object. Please note that the destructured values can still be undefined.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I think this will look cleaner no matter how many optional parameters we have. We can even still omit the &lt;code&gt;optionals&lt;/code&gt; completely like before.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;myFunction("Call me maybe", 12345);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Win-win for me! &lt;/p&gt;




&lt;p&gt;So, what do you think? Maybe you have a better way to write optionals? Let us know!&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>codequality</category>
      <category>todayilearned</category>
    </item>
    <item>
      <title>Improve code readability with conditional safeguards</title>
      <dc:creator>Moses Karunia</dc:creator>
      <pubDate>Tue, 15 Oct 2019 08:44:50 +0000</pubDate>
      <link>https://dev.to/moseskarunia/improve-code-readability-with-conditional-safeguards-446d</link>
      <guid>https://dev.to/moseskarunia/improve-code-readability-with-conditional-safeguards-446d</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;"You shall not pass!" - Gandalf the Grey, 2001&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  TL;DR
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Define what your code supposed to do.&lt;/li&gt;
&lt;li&gt;Write safeguards. One safeguard should define one specific condition.&lt;/li&gt;
&lt;li&gt;Don't use &lt;code&gt;else&lt;/code&gt;, if able.&lt;/li&gt;
&lt;li&gt;Don't nest &lt;code&gt;if&lt;/code&gt;, if able.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;Conditional is one of basic fundamentals in programming. And the most basic of many kind of conditionals in programming, is &lt;code&gt;if&lt;/code&gt; statement.&lt;/p&gt;

&lt;p&gt;Writing an &lt;code&gt;if&lt;/code&gt; statement is easy, but if we are not careful, it can easily leads to giant spaghetti code mess, hard to read and debug.&lt;/p&gt;

&lt;p&gt;I think, there are (not limited to) two things can lead to messy codes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Overnesting &lt;code&gt;if&lt;/code&gt; statements&lt;/li&gt;
&lt;li&gt;Unnecessary &lt;code&gt;else&lt;/code&gt; statements&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You might say, &lt;em&gt;"Just write a comment to explain!"&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;Well, comments are great and can be helpful. But they should not be used to justify a messy code.&lt;/p&gt;

&lt;p&gt;So this time, I'm going to share with you, about how I usually write my conditionals.&lt;/p&gt;

&lt;p&gt;I don't know what the official name of it, LOL. But I think I first read it somewhere as &lt;strong&gt;SAFEGUARDING&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  CASE STUDY
&lt;/h1&gt;

&lt;p&gt;To do this, first, we need to determine what our function should do. To make it easier to explain, let's jump to code: &lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Code is in Typescript)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Say we want to add a polymorph skill to our game. Therefore, we write this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const polymorph = (caster: Person, target: Person) : Beast =&amp;gt; {
  return new Beast(from: target);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Plain and simple. Now our target is polymorph-ed if we call the function.&lt;/p&gt;

&lt;p&gt;But wait, not everyone should be able to cast polymorph! It will be broken if a knight is able to cast it.&lt;/p&gt;

&lt;p&gt;So, let's &lt;strong&gt;safeguard&lt;/strong&gt; it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const polymorph = (caster: Person, target: Person) : Beast =&amp;gt; {
  try {
    if(caster.class !== 'WIZARD') {
      throw new Error('Only wizard can cast polymorph!');
    }

    return new Beast(from: target);
  } catch (error) {
      throw error;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There you go! Now, only wizards can cast polymorph. &lt;/p&gt;

&lt;p&gt;Hmm. &lt;/p&gt;

&lt;p&gt;Btw, aren't wizards need 100 mana to cast polymorph? Well, let's add the mana cost to the logic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const polymorph = (caster: Person, target: Person) : Beast =&amp;gt; {
  try {
    if(caster.class !== 'WIZARD' &amp;amp;&amp;amp; caster.mana &amp;lt; 100) {

      if(caster.mana &amp;lt; 100) {
        throw new Error('Not enough mana!');
      }

      throw new Error('Only wizard can cast polymorph!');
    }

    return new Beast(from: target);
  } catch (error) {
      throw error;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Umm. Nested &lt;code&gt;if&lt;/code&gt; statement. Can we un-nest it?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const polymorph = (caster: Person, target: Person) : Beast =&amp;gt; {
  try {
    if(caster.class !== 'WIZARD') {
      throw new Error('Only wizard can cast polymorph!');
    }

    if(caster.mana &amp;lt; 100) {
      throw new Error('Not enough mana!');
    }

    return new Beast(from: target);
  } catch (error) {
      throw error;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ah nice. &lt;/p&gt;

&lt;p&gt;I think it's better. Improved readability by separating each safeguard's concern.&lt;/p&gt;

&lt;p&gt;Wait. How if our target is currently immune?&lt;/p&gt;

&lt;p&gt;Alright, let's add the logic to our function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const polymorph = (caster: Person, target: Person) : Beast =&amp;gt; {
  try {
    if(caster.class !== 'WIZARD') {
      throw new Error('Only wizard can cast polymorph!');
    }

    if(caster.mana &amp;lt; 100) {
      throw new Error('Not enough mana!');
    }

    if(target.isImmune) {
      throw new Error('Target is immune!');
    }

    return new Beast(from: target);
  } catch (error) {
      throw error;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There you go, now polymorph can only cast by wizards, requires 100 mana, and cannot pierce immune targets.&lt;/p&gt;

&lt;p&gt;And now, both of our players as well as the code maintainers are happy.&lt;/p&gt;




&lt;h1&gt;
  
  
  SUMMARY
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Define what your code supposed to do. &lt;em&gt;(It'll be better if we separate the concern of each functions)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Write safeguards. One safeguard should define one specific condition.&lt;/li&gt;
&lt;li&gt;Don't use &lt;code&gt;else&lt;/code&gt;, if able.&lt;/li&gt;
&lt;li&gt;Don't nest &lt;code&gt;if&lt;/code&gt;, if able.&lt;/li&gt;
&lt;/ol&gt;




&lt;h1&gt;
  
  
  CLOSING
&lt;/h1&gt;

&lt;p&gt;What I really like about safeguard, is because it improve code readability and easier to define structured error messages. &lt;/p&gt;

&lt;p&gt;It's like saying: &lt;em&gt;"Ok, this is what the code should do. But, look at the safeguards! They prevents the code to function under wrong circumstances."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Oh, before anyone fire out their gun, I'm not against &lt;code&gt;else&lt;/code&gt; statements. It's necessary sometimes. After all, it exists for a reason. But in some cases where we can omit it and improve code readability, why even bother to write it?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Less is more&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  NOTE
&lt;/h1&gt;

&lt;p&gt;For you who don't know, &lt;code&gt;throw&lt;/code&gt;-ing an error means stopping the function from continuing. It's similar like writing &lt;code&gt;return;&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>codequality</category>
    </item>
  </channel>
</rss>
