<?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>Forem: Matthew Groves</title>
    <description>The latest articles on Forem by Matthew Groves (@mpeng3).</description>
    <link>https://forem.com/mpeng3</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%2F235596%2Ff9fe2d5e-ad8c-49e1-825f-503826bc3585.png</url>
      <title>Forem: Matthew Groves</title>
      <link>https://forem.com/mpeng3</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/mpeng3"/>
    <language>en</language>
    <item>
      <title>Matt's Tidbits #103 - Launching an app from a URL</title>
      <dc:creator>Matthew Groves</dc:creator>
      <pubDate>Tue, 02 Nov 2021 15:12:38 +0000</pubDate>
      <link>https://forem.com/mpeng3/matts-tidbits-103-launching-an-app-from-a-url-3eo</link>
      <guid>https://forem.com/mpeng3/matts-tidbits-103-launching-an-app-from-a-url-3eo</guid>
      <description>&lt;p&gt;This week's tidbit will show you how to launch an app when a user clicks on a link. &lt;a href="https://medium.com/nerd-for-tech/matts-tidbits-102-debugging-a-perplexing-view-binding-issue-69d2bb81999c"&gt;Last time, I wrote about debugging a view binding issue in Android.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Have you ever had an app launch on your mobile device when you click a link in an email, on a webpage, etc. and wondered how to do the same thing for your app? Wonder no more, because in this simple guide I will show you how to accomplish this!&lt;/p&gt;

&lt;h1&gt;
  
  
  Android
&lt;/h1&gt;

&lt;p&gt;On Android, this can be accomplished by defining an &lt;code&gt;&amp;lt;intent-filter&amp;gt;&lt;/code&gt; in your app's &lt;code&gt;AndroidManifest.xml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here's a simple example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;intent-filter&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;action&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.intent.action.VIEW"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;category&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.intent.category.DEFAULT"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;category&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.intent.category.BROWSABLE"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;data&lt;/span&gt; 
    &lt;span class="na"&gt;android:scheme=&lt;/span&gt;&lt;span class="s"&gt;"https"&lt;/span&gt;
    &lt;span class="na"&gt;android:host=&lt;/span&gt;&lt;span class="s"&gt;"matthew-b-groves.medium.com"&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/intent-filter&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Doing something like this would cause any link that began with &lt;code&gt;https://matthew-b-groves.medium.com&lt;/code&gt; (the URL for my Medium profile) to launch this app instead.&lt;/p&gt;

&lt;p&gt;You can even define multiple &lt;code&gt;&amp;lt;data&amp;gt;&lt;/code&gt; listings to allow multiple URL patterns to invoke your app. &lt;em&gt;(Note that any possible combination of schemes/hosts that you have defined will match - even across &lt;code&gt;&amp;lt;data&amp;gt;&lt;/code&gt; entries)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Depending on your desired behavior, you can even use something completely custom for the &lt;code&gt;android:scheme&lt;/code&gt;, such as &lt;code&gt;mattstidbits&lt;/code&gt;, and omit the &lt;code&gt;android:host&lt;/code&gt; property entirely. This would allow any URL starting with &lt;code&gt;mattstidbits://&lt;/code&gt; to launch your app. However, this will only work if the user has your app is installed. If you want to direct the user to the Play Store listing for your app if they don't have it installed, you'll want to use an &lt;code&gt;http&lt;/code&gt; or &lt;code&gt;https&lt;/code&gt; scheme and a host/domain that you own. Then, you can follow &lt;a href="https://developer.android.com/studio/write/app-link-indexing#associatesite"&gt;these instructions&lt;/a&gt; to create a JSON file that you can embed on your website that will instruct browsers to redirect users to the Play Store listing page for your app.&lt;/p&gt;

&lt;p&gt;If you want to have your app access information that's embedded in the URL (so you can take them to a specific screen within the app), you'll want to add something like the following to your application's &lt;code&gt;onCreate&lt;/code&gt; method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can then verify that the action was &lt;code&gt;Intent.ACTION_VIEW&lt;/code&gt; and grab the &lt;code&gt;uri&lt;/code&gt; that was passed in and use the methods/properties of the &lt;code&gt;Uri&lt;/code&gt; class to pull out information from the URI to help you handle the request.&lt;/p&gt;

&lt;p&gt;It's also a good idea to test your deep linking, which you can do on a simulator or physical device using the &lt;code&gt;adb&lt;/code&gt; command, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;adb shell am start -d "your-deep-link-url"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Android developer documentation for implementing deep linking is really excellent, which you can find here: &lt;a href="https://developer.android.com/training/app-links/deep-linking"&gt;https://developer.android.com/training/app-links/deep-linking&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  iOS
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;Disclaimer: I am not an iOS developer by trade, so I can't provide nearly the level of detail that I can for Android.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Apple appears to offer two different mechanisms for launching an app from a URL - URL Schemes and Universal Links.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app"&gt;URL Schemes&lt;/a&gt; are easier/faster to implement, but prompt the user for permission and don't work if the app is not installed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.apple.com/ios/universal-links/"&gt;Universal Links&lt;/a&gt; require you to have control of the domain (much like Google's App Links that I described above), so they require more work to set up, but they won't prompt the user and allow you to provide a fallback URL if the user doesn't have the app installed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article does a good job of explaining some of the differences: &lt;a href="https://medium.com/wolox/ios-deep-linking-url-scheme-vs-universal-links-50abd3802f97"&gt;https://medium.com/wolox/ios-deep-linking-url-scheme-vs-universal-links-50abd3802f97&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For now, let's focus on URL Schemes, since that's the approach I have worked with before. To set one up, all you have to do is specify the scheme in Xcode via the Info tab in your project's settings. Note that unlike Android, iOS only lets you define the scheme (the part that comes before the &lt;code&gt;://&lt;/code&gt; in a URL). So, you could enter &lt;code&gt;mattstidbits&lt;/code&gt; in the "URL Schemes" field, so any links beginning with &lt;code&gt;mattstidbits://&lt;/code&gt; would launch your app (if it's installed).&lt;/p&gt;

&lt;p&gt;In your &lt;code&gt;Info.plist&lt;/code&gt; file this shows up under the &lt;code&gt;CFBundleURLSchemes&lt;/code&gt; key.&lt;/p&gt;

&lt;p&gt;If you want your app to access the information that's stored in the URL, then you'll need to handle this inside of your app delegate's &lt;code&gt;application()&lt;/code&gt; method. There's a &lt;code&gt;url&lt;/code&gt; argument that will contain the data.&lt;/p&gt;

&lt;p&gt;As with Android, you can test these deep links by running the following terminal command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;xcrun simctl openurl booted "your-deep-link-url"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Again, I don't pretend to be an iOS developer, so please see the &lt;a href="https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app"&gt;official documentation&lt;/a&gt; for how to do this.)&lt;/p&gt;

&lt;h1&gt;
  
  
  React Native
&lt;/h1&gt;

&lt;p&gt;If you've been following my tidbits for a while, you probably wondered if I would touch on this - here's how to do this in React Native!&lt;/p&gt;

&lt;p&gt;React Native has two different setups - if you are using Expo, follow &lt;a href="https://reactnavigation.org/docs/deep-linking/#set-up-with-expo-projects"&gt;these instructions&lt;/a&gt; to specify the scheme you'd like to use within Expo's JSON config.&lt;/p&gt;

&lt;p&gt;However, if you are not using Expo, you generally need to follow the same steps above for iOS/Android to set up deep linking in your &lt;code&gt;AndroidManifest.xml&lt;/code&gt; and &lt;code&gt;Info.plist&lt;/code&gt;. To get this working in a React Native CLI project, you should follow &lt;a href="https://reactnavigation.org/docs/deep-linking/#set-up-with-bare-react-native-projects"&gt;these instructions&lt;/a&gt; to configure your project. Note that for iOS you'll need to add some special code to your AppDelegate to make this work.&lt;/p&gt;

&lt;p&gt;Note that both of these options assume you are using React Navigation for managing navigation within your app (which I highly recommend you do!)&lt;/p&gt;

&lt;p&gt;If you want to be able to actually do something with the URL (and not just simply invoke the app), you will need to configure a &lt;code&gt;linking&lt;/code&gt; object and assign that to your &lt;code&gt;NavigationContainer&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;linking&lt;/code&gt; object is a little funky, in that it's like a copy of your navigation graph. It gives you the power to map URL parameters to internal route names/paths, but does require you to match your app's navigation graph precisely.&lt;/p&gt;

&lt;p&gt;For example, you might set this up as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;screens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;Tidbit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;post/:id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;Profile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&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;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;linking&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;prefixes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://matthew-b-groves.medium.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;NavigationContainer&lt;/span&gt; &lt;span class="nx"&gt;linking&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;linking&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Navigator&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Screen&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Tidbit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;PostDetailScreen&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Screen&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Profile&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;ProfileScreen&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Stack.Navigator&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/NavigationContainer&lt;/span&gt;&lt;span class="err"&gt;&amp;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;Where this can start to get a little tedious is if you have nested navigators (which you likely do), your &lt;code&gt;linking&lt;/code&gt; object will need to also match that nesting.&lt;/p&gt;

&lt;p&gt;For more details, see &lt;a href="https://reactnavigation.org/docs/configuring-links"&gt;this article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To test the link with an Expo project, run the following command (substituting &lt;code&gt;ios&lt;/code&gt; in place of &lt;code&gt;android&lt;/code&gt; below if you'd like to change what platform you're targeting):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx uri-scheme open "your-deep-link-url://127.0.0.1:19000" --android
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a non-Expo project, you can test the deep linking via the native iOS/Android commands described in the sections above.&lt;/p&gt;

&lt;h1&gt;
  
  
  Overall strategies
&lt;/h1&gt;

&lt;p&gt;What can we take away from this?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deep linking on both iOS/Android/React Native provides sophisticated functionality.&lt;/li&gt;
&lt;li&gt;In nearly all cases, you probably want your links to have the same format across iOS/Android for consistency's sake (having links work on either platform seamlessly)&lt;/li&gt;
&lt;li&gt;I would recommend starting with the simplest approach and building from there - there can be a lot of red tape to work through to get files changed in your company's/project's website in order to use the more sophisticated App Links (Android) or Universal Links (iOS), so if you're able to get by with the more basic deep linking/URL schemes (where you don't need to modify a website), then start with that.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Interested in working with me in the awesome Digital Products team here at Accenture? We have an opening:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.accenture.com/us-en/careers/jobdetails?id=00960583_en&amp;amp;title=Mobile+Developer"&gt;Mobile Developer (Northeast locations)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Do you have other deep linking tips you'd like to share? Let me know in the comments below!&lt;/p&gt;

</description>
      <category>mattstidbits</category>
      <category>android</category>
      <category>ios</category>
      <category>reactnative</category>
    </item>
    <item>
      <title>Matt's Tidbits #102 - Debugging a perplexing view binding issue</title>
      <dc:creator>Matthew Groves</dc:creator>
      <pubDate>Tue, 12 Oct 2021 13:09:35 +0000</pubDate>
      <link>https://forem.com/mpeng3/matt-s-tidbits-102-debugging-a-perplexing-view-binding-issue-369g</link>
      <guid>https://forem.com/mpeng3/matt-s-tidbits-102-debugging-a-perplexing-view-binding-issue-369g</guid>
      <description>&lt;p&gt;This week I have a tidbit (plus a bonus!) to share about converting an existing app to using Android view binding. &lt;a href="https://medium.com/nerd-for-tech/matts-tidbits-101-how-to-write-a-good-bug-report-818ab8994ada"&gt;Last time, I wrote about how to write a good bug report.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, the bonus! (Shouldn't dessert always come first?) I recently started getting back into some Android development (after working in React Native for the past 6+ months), and opened up the shiny new Arctic Fox release of Android studio. Upon doing so, however, I noticed that many of my familiar keyboard shortcuts no longer worked (such as ⌘W for closing an editor window). It appears that Android Studio changed the default keyboard mappings - so if you run into this, just go into Preferences-&amp;gt;Keymap and select "macOS" instead of "IntelliJ IDEA Classic".&lt;/p&gt;

&lt;p&gt;Now, for the main tidbit. 😉&lt;/p&gt;

&lt;p&gt;The reason I came back to Android is because I am updating an internal project to work with all of the latest tools/paradigms/etc. This app still uses MVP as its paradigm, and even still uses Butterknife (which has been deprecated for more than a year). The UI for this app is fairly simple - it has a RecyclerView, and when you click on one of those items it launches a new activity. In the process of switching over to Android view binding, however, I ran into a bug - nothing was rendering in my RecyclerView!&lt;/p&gt;

&lt;p&gt;I spent WAY longer than I'd like to admit debugging this - putting in breakpoints, print statements, double-checking that the data was being passed to the right place, trying various combinations of calling &lt;code&gt;notifyDataSetChanged()&lt;/code&gt; and &lt;code&gt;submitList()&lt;/code&gt; - all to no avail. No matter what I did, the &lt;code&gt;onCreateViewHolder()&lt;/code&gt; and &lt;code&gt;onBindViewHolder()&lt;/code&gt; methods of my adapter were never being called.&lt;/p&gt;

&lt;p&gt;Stumped? Thankfully, the solution ended up being pretty simple. Once I looked at a complete implementation for a screen that had a working RecyclerView, I noticed a key difference.&lt;/p&gt;

&lt;p&gt;In the activity that wasn't working, I had the following line in the &lt;code&gt;onCreate()&lt;/code&gt; method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;setContentView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;my_activity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, the activity that worked had this line instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;setContentView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;binding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRoot&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That was it! Switching to the newer version that used the &lt;code&gt;binding&lt;/code&gt; object I had saved was enough to do the trick.&lt;/p&gt;

&lt;p&gt;What did I learn from this?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;I need to do some more studying to make sure I'm staying up-to-date with the latest tools (I haven't honestly used view binding that much - I like what I see thus far, but I didn't really know what to look for at first).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Take a break/talk to someone else - I will give my wife the credit for this one - she's not a programmer, but asked me what I was trying to solve, and simply in the process of trying to explain it and showing her the code, I stumbled upon this key difference.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Simplify the problem/challenge your assumptions - I should have done this sooner - stripping out all unnecessary code and sanity-checking myself to make sure I could reproduce a working solution, and then comparing that with what wasn't working.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I hope you learned something, and that if/when you convert your old Android UI code to use view binding that it's a smoother/faster transition than this was for me!&lt;/p&gt;




&lt;p&gt;Interested in working with me in the awesome Digital Products team here at Accenture? We have several open roles, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.accenture.com/us-en/careers/jobdetails?id=00960587_en&amp;amp;title=Native+Mobile+Developer"&gt;Mobile Developer (Northeast locations)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.accenture.com/us-en/careers/jobdetails?id=R00036232_en&amp;amp;title=Senior+iOS+Developer"&gt;Senior iOS Developer (Southern locations)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.accenture.com/us-en/careers/jobdetails?id=R00027147_en&amp;amp;title=Android+Mobile+Developer"&gt;Android Mobile Developer (Southern locations)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.accenture.com/us-en/careers/jobdetails?id=R00027113_en&amp;amp;title=iOS+Mobile+Development+Lead"&gt;iOS Mobile Development Lead (Southern locations)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;What has your experience with using view binding been like? Let me know in the comments below!&lt;/p&gt;

</description>
      <category>mattstidbits</category>
      <category>android</category>
      <category>debugging</category>
      <category>tidbittuesday</category>
    </item>
    <item>
      <title>Matt's Tidbits #101 - How to write a good bug report</title>
      <dc:creator>Matthew Groves</dc:creator>
      <pubDate>Tue, 28 Sep 2021 14:13:34 +0000</pubDate>
      <link>https://forem.com/mpeng3/matt-s-tidbits-101-how-to-write-a-good-bug-report-348m</link>
      <guid>https://forem.com/mpeng3/matt-s-tidbits-101-how-to-write-a-good-bug-report-348m</guid>
      <description>&lt;p&gt;This week I have a story to share about filing bug reports -why they're important, and what makes a "good" one. &lt;a href="https://medium.com/nerd-for-tech/matts-tidbits-100-all-about-teams-856771e938de"&gt;Last time, (sorry for the delay between posts!) I wrote about some Teams-related tips.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've written several tidbits before where I file a bug report, but I have an exciting update to share - one of the bugs I filed has recently been fixed as a direct result of my report!!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://matthew-b-groves.medium.com/matts-tidbits-56-be-careful-with-jvmoverloads-165d87581820"&gt;In February of 2020 I wrote about a bug&lt;/a&gt; I had discovered where Android Studio's "quick fix" suggestion for Kotlin-based classes that derive from Android view components dangerously auto-generate a constructor with the @JvmOverloads annotation which causes the default style/theme properties to be ignored.&lt;/p&gt;

&lt;p&gt;The report describing the bug is here: &lt;a href="https://issuetracker.google.com/issues/149986188"&gt;https://issuetracker.google.com/issues/149986188&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What's the lesson to be learned here? Aside from my original caution around using @JvmOverloads, what I would like to impart this time is around how to write a good bug report. This is really one of the key differences between the bugs that get fixed and the ones that get ignored.&lt;/p&gt;

&lt;p&gt;So, what goes into a good bug report?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;A clear description of the problem - if people can't understand what you're talking about, it will be disregarded very early on in the process. The trick is to be very precise about what the issue is, with a sufficient level of detail - as a developer, I've seen bug reports that say " doesn't work" - that's not good enough. Also try to specify exactly what versions of all components you are using (Android Studio, Kotlin, libraries, phone make/model, OS, etc.), and if you can, do a little extra testing to determine and be able to explain what configurations may be impacted by this issue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An easily reproducible test case - it's one thing to understand what the problem is, but you can greatly boost the likelihood of your issue being addressed if you do a little extra work to put together a sample project that clearly demonstrates the issue. Don't just upload a copy of your entire project - the smaller/simpler an example you can provide, the better.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A description of what the expected behavior should be - if the person investigating your bug has followed you through the first 2 items above, but you haven't spelled out what you think should happen, your bug may not get worked on - they may believe that it "functions as designed". This is where you can use some persuasive/logical arguments to clearly explain why the current behavior is wrong, and what it should do instead.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Double-check your bug report for errors (logical errors, missing information, typos, poor grammar, etc.) If there are bugs in your bug report, it's not going to be taken as seriously - so be sure to double-check it for errors, and try to write it in a professional tone. Using full sentences with proper capitalization, etc. eliminates the hurdle of the person reading it possibly concluding that you don't know what you're talking about.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Publicize the issue and get other people on board - the more people who are clearly affected by the issue, the more highly it will be prioritized. So, once you have submitted the issue, share it as broadly as you are able - tell your coworkers past &amp;amp; current and ask them to do the same, and consider writing an article about it to increase its visibility.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Follow the above steps, and with any luck, your issue will be resolved! The quality of especially open source projects increasingly relies on members of the community reporting the issues they're experiencing. And, if it seems like your bug is taking a long time to be fixed, consider trying to resolve it yourself! Open source projects often have limited developer resources, so if you provide a solid fix for the issue yourself (or at least have done some research into the cause and provide a suggestion for how to fix it), this can be another helpful boost towards getting the issue resolved.&lt;/p&gt;

&lt;p&gt;Finally, note that the above suggestions don't just apply to external bug reports - these same strategies can be used to supercharge your internal bug reports as well!&lt;/p&gt;

&lt;p&gt;For reference, here are two other Android Studio bugs I have filed previously which have also been resolved (both of these indirectly, but it can still be helpful the project's developers to provide additional data points):&lt;br&gt;
&lt;a href="https://issuetracker.google.com/issues/131403382"&gt;https://issuetracker.google.com/issues/131403382&lt;/a&gt;&lt;br&gt;
&lt;a href="https://issuetracker.google.com/issues/143971679"&gt;https://issuetracker.google.com/issues/143971679&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Interested in working with me in the awesome Digital Products team here at Accenture? We have several open roles, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.accenture.com/us-en/careers/jobdetails?id=00960587_en&amp;amp;title=Native+Mobile+Developer"&gt;Mobile Developer #1 (Northeast locations)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.accenture.com/us-en/careers/jobdetails?id=00960583_en&amp;amp;title=Mobile+Developer"&gt;Mobile Developer #2 (Northeast locations)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.accenture.com/us-en/careers/jobdetails?id=00983613_en&amp;amp;title=Engineering+Director"&gt;Engineering Director (Boston or Philadelphia)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.accenture.com/us-en/careers/jobdetails?id=R00036232_en&amp;amp;title=Senior+iOS+Developer"&gt;Senior iOS Developer (Southern locations)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.accenture.com/us-en/careers/jobdetails?id=R00027147_en&amp;amp;title=Android+Mobile+Developer"&gt;Android Mobile Developer (Southern locations)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.accenture.com/us-en/careers/jobdetails?id=R00027113_en&amp;amp;title=iOS+Mobile+Development+Lead"&gt;iOS Mobile Development Lead (Southern Locations)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Do you have other suggestions for how to write a good bug report? Let me know in the comments below!&lt;/p&gt;

</description>
      <category>mattstidbits</category>
      <category>android</category>
      <category>opensource</category>
      <category>tidbittuesday</category>
    </item>
    <item>
      <title>Matt's Tidbits #100 - All About Teams</title>
      <dc:creator>Matthew Groves</dc:creator>
      <pubDate>Tue, 03 Aug 2021 14:23:07 +0000</pubDate>
      <link>https://forem.com/mpeng3/matt-s-tidbits-100-all-about-teams-14on</link>
      <guid>https://forem.com/mpeng3/matt-s-tidbits-100-all-about-teams-14on</guid>
      <description>&lt;p&gt;This week I have a few Teams-related tidbits to share! &lt;a href="https://medium.com/nerd-for-tech/matts-tidbits-99-handling-null-elegantly-6d95200dae4"&gt;Last time I wrote about elegantly handling null/undefined values in a variety of languages.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🎉 First of all, a little celebration for my 100th tidbit! 🥳 &lt;br&gt;
The frequency may have slowed down a little bit from when I first started in January of 2019 (because life and work both happen!), but as long as there's a willing audience, I have no plans to stop writing these!&lt;/p&gt;

&lt;p&gt;MS Teams - love it or hate it, it's here to stay. Regardless of your personal viewpoint though, you will probably benefit from these tidbits to help you use it more effectively!&lt;/p&gt;

&lt;p&gt;#1 - In the past few weeks, I noticed that the MS Teams icon in the Dock on my Mac stopped indicating how many unread messages I had. This is a serious issue, as it's one of the primary ways my team communicates, and caused me to be slow to respond to countless messages. The good news is, I found a way to fix this!!&lt;/p&gt;

&lt;p&gt;All you have to do is the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open MS Teams, click the 3 dots in the upper-right corner next to your profile photo, and select "Settings"&lt;/li&gt;
&lt;li&gt;Open the "Notifications" section&lt;/li&gt;
&lt;li&gt;Under "Notification style", ensure that "Mac" is selected - for some reason, the option that was active for me, "Teams built-in" does not work.&lt;/li&gt;
&lt;li&gt;Verify in macOS System Preferences, under "Notifications" that "Allow Notifications from Microsoft Teams" is enabled and "Badge app icon" is checked. Now have someone send you a message and it should work like a charm!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;#2 - If you're in a Teams call and, like me, find it a little slow/inconvenient to click the mute button, there's a handy shortcut you can use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click the mute button (once, probably early on in the meeting) - this will display a selection box around the mute button&lt;/li&gt;
&lt;li&gt;... which means that you can press the space bar to perform the operation of clicking the button! As long as you don't navigate somewhere else in Teams, and Teams stays the active application, this trick will work!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(Thanks to our Northeast Digital Products lead, Binta Patel, for this tip!)&lt;/p&gt;

&lt;p&gt;Speaking of teams, I've recently taken on a new role on my team- I am now one of the co-leads for our mobile team in the Northeast. I'm thrilled to have the opportunity to help guide this amazing group of people and set the direction for where we're headed! We have a bunch of openings, so if you'd like to join me on this journey (or know someone who might be a good fit), please check out the following postings, and feel free to send me a message if you have any questions! (All postings are for the Northeast - Boston, NYC, etc. unless specified otherwise)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.accenture.com/us-en/careers/jobdetails?id=R00027111_en&amp;amp;title=iOS+Mobile+Developer+Apprentice"&gt;iOS Mobile Developer Apprentice&lt;/a&gt; (closing soon!)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.accenture.com/us-en/careers/jobdetails?id=R00027103_en&amp;amp;title=UI%2fUX+Design+Apprentice"&gt;UI/UX Design Apprentice&lt;/a&gt; (closing soon!)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.accenture.com/us-en/careers/jobdetails?id=R00027063_en&amp;amp;title=Android+Developer+Apprentice"&gt;Midwest Android Mobile Developer Apprentice&lt;/a&gt; (closing soon!)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.accenture.com/us-en/careers/jobdetails?id=R00027054_en&amp;amp;title=iOS+Developer+Apprentice"&gt;Midwest iOS Mobile Developer Apprentice&lt;/a&gt; (closing soon!)

&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.accenture.com/us-en/careers/jobdetails?id=00960583_en&amp;amp;title=Mobile+Developer"&gt;Mobile Developer #1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.accenture.com/us-en/careers/jobdetails?id=00960587_en&amp;amp;title=Native+Mobile+Developer"&gt;Mobile Developer #2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.accenture.com/us-en/careers/jobdetails?id=R00033887_en&amp;amp;title=Mobile+%26+Web+Engineering+Director"&gt;Mobile &amp;amp; Web Engineering Director&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.accenture.com/us-en/careers/jobdetails?id=00961693_en&amp;amp;title=DevOps+Engineer"&gt;DevOps Engineer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do you have other MS Teams-related tips? Let me know in the comments below!&lt;/p&gt;

</description>
      <category>mattstidbits</category>
      <category>teams</category>
      <category>tidbittuesday</category>
    </item>
    <item>
      <title>Matt's Tidbits #99 - Handling null elegantly</title>
      <dc:creator>Matthew Groves</dc:creator>
      <pubDate>Tue, 06 Jul 2021 14:16:09 +0000</pubDate>
      <link>https://forem.com/mpeng3/matt-s-tidbits-99-handling-null-elegantly-2jnj</link>
      <guid>https://forem.com/mpeng3/matt-s-tidbits-99-handling-null-elegantly-2jnj</guid>
      <description>&lt;p&gt;&lt;a href="https://medium.com/nerd-for-tech/matts-tidbits-98-the-truth-will-set-you-free-unless-you-re-using-javascript-46f841583636"&gt;Last week I wrote about some truthiness edge cases in JavaScript.&lt;/a&gt; This time, I have a quick tidbit on elegantly handling null/undefined values.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;null&lt;/code&gt; - called the "Billion-Dollar Mistake" by its inventor, C.A.R. Hoare - most programmers are probably intimately familiar with this (and why it might be categorized as a mistake!)&lt;/p&gt;

&lt;p&gt;We've certainly all written some code like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if(foo != null) {
  // Do something with foo
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But, what if &lt;code&gt;foo&lt;/code&gt; is an object with multiple levels of nested objects? You'd probably agree that it gets a little cumbersome to write something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if(foo != null) {
  if(foo.bar != null) {
    if(foo.bar.baz != null) {
      // Now it's safe to use foo.bar.baz
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some more modern languages (Kotlin, JavaScript 2020, Swift, etc.) have support for what's known as "safe calls/optional chaining", and it looks like this:&lt;br&gt;
&lt;code&gt;x = foo?.bar?.baz?.doSomething()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;?&lt;/code&gt; indicates that the right-hand side should only be evaluated if the left-hand side is not &lt;code&gt;null&lt;/code&gt;. However, if any part of this expression is &lt;code&gt;null&lt;/code&gt;, then &lt;code&gt;x&lt;/code&gt; will be &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;What if we wanted to specify what value &lt;code&gt;x&lt;/code&gt; should have in case any of the &lt;code&gt;null&lt;/code&gt; checks fail? We could obviously achieve this by checking if &lt;code&gt;x&lt;/code&gt; is &lt;code&gt;null&lt;/code&gt; after the statement and then assigning a different value to it, but if we wanted &lt;code&gt;x&lt;/code&gt; to be a constant, this would not be possible.&lt;/p&gt;

&lt;p&gt;Some languages support a ternary operator, so you could do something like this:&lt;br&gt;
&lt;code&gt;x = foo?.bar?.baz ? foo?.bar?.baz?.doSomething() : &amp;lt;fallback value&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In my opinion, this is repetitive, and it's also error-prone - if &lt;code&gt;doSomething()&lt;/code&gt; returns &lt;code&gt;null&lt;/code&gt;, then &lt;code&gt;x&lt;/code&gt; could still be &lt;code&gt;null&lt;/code&gt;! You could work around this by putting &lt;code&gt;?.doSomething()&lt;/code&gt; before the &lt;code&gt;?&lt;/code&gt; of the ternary operator, but are we sure it's safe to call &lt;code&gt;doSomething()&lt;/code&gt; more than once? It could have side-effects that introduce subtle bugs into our code or be resource intensive and degrade our application's performance.&lt;/p&gt;

&lt;p&gt;Instead, I'd like to propose a better way - the null(ish) coalescing operator:&lt;br&gt;
&lt;code&gt;x = foo?.bar?.baz?.doSomething() ?? &amp;lt;fallback value&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This way, &lt;code&gt;x&lt;/code&gt; can still be a constant, we'll catch any possible &lt;code&gt;null&lt;/code&gt; values in the entire chain, and we're only calling &lt;code&gt;doSomething()&lt;/code&gt; one time (at most).&lt;/p&gt;

&lt;p&gt;Now, if you caught it, why did I call this the null*(ish)* coalescing operator? That's because in JavaScript, the optional chaining operator and null coalescing operator apply to BOTH &lt;code&gt;null&lt;/code&gt; and &lt;code&gt;undefined&lt;/code&gt;. Neat, huh?&lt;/p&gt;

&lt;p&gt;I had known about this concept from working in Kotlin, where this functionality is called the "Elvis operator". It's written as &lt;code&gt;?:&lt;/code&gt; - which looks a little bit like the top of Elvis' head (eyes &amp;amp; his signature curly hairdo) - plus, in the Kotlin community we can remember that anything that happens to the right of the operator is what occurs when "Elvis has left the building" (i.e. if you've encountered a &lt;code&gt;null&lt;/code&gt; and left the optional chain) And yes, I know - Programmers can be real nerds sometimes. ;-)&lt;/p&gt;

&lt;p&gt;Now that I've been working in React Native using TypeScript (which is built on top of JavaScript), I discovered that this functionality also exists there. Which led me to discover that Swift has this same concept too - the "nil coalescing operator" (represented by &lt;code&gt;??&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;All of this to say - I think it's really exciting that more and more modern programming languages are converging and supporting ever more similar ways of writing code. Each language will always have its quirks (as well as advantages &amp;amp; drawbacks), but I think we're getting much closer to a world where Android developers can read through an iOS codebase and understand what's happening (not so back when they were still written in Objective C), or a traditional web developer can work on a mobile application (already a reality thanks to technologies such as React Native).&lt;/p&gt;

&lt;p&gt;Know of other languages that support some variant of optional chaining/null coalescing? I'd love to hear from you in the comments!&lt;/p&gt;

&lt;p&gt;Interested in working with me in the awesome Digital Products team here at Accenture? We're hiring &lt;a href="https://www.accenture.com/us-en/careers/jobdetails?id=00960587_en&amp;amp;title=Native+Mobile+Developer"&gt;mobile developers&lt;/a&gt;, &lt;a href="https://www.accenture.com/us-en/careers/jobdetails?id=00906120_en&amp;amp;title=Web+Developer"&gt;web developers&lt;/a&gt;, and &lt;a href="https://www.accenture.com/us-en/careers/jobsearch?jk=%22Digital%20Products%22&amp;amp;sb=0&amp;amp;pg=1&amp;amp;is_rj=0&amp;amp;ct=ma%20-%20cambridge%7Cny%20-%20new%20york"&gt;more&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>mattstidbits</category>
      <category>javascript</category>
      <category>kotlin</category>
      <category>swift</category>
    </item>
    <item>
      <title>Matt's Tidbits #98 - The truth will set you free (unless you're using JavaScript)</title>
      <dc:creator>Matthew Groves</dc:creator>
      <pubDate>Tue, 29 Jun 2021 12:59:19 +0000</pubDate>
      <link>https://forem.com/mpeng3/matt-s-tidbits-98-the-truth-will-set-you-free-unless-you-re-using-javascript-3lpk</link>
      <guid>https://forem.com/mpeng3/matt-s-tidbits-98-the-truth-will-set-you-free-unless-you-re-using-javascript-3lpk</guid>
      <description>&lt;p&gt;&lt;a href="https://medium.com/nerd-for-tech/matts-tidbits-97-running-debugging-individual-jest-unit-tests-36f7464fbaf9"&gt;Last time I shared a quick tidbit about running individual unit tests.&lt;/a&gt; This time, I want to share a few interesting things I learned while debugging a failing unit test.&lt;/p&gt;

&lt;p&gt;If you've used JavaScript for any length of time, you may have encountered its slightly special behavior around boolean expressions. In many other languages, &lt;code&gt;if&lt;/code&gt; statements can only contain boolean expressions - either a boolean variable, or some other expression which returns a boolean value, such as: greater than, less than, equal to, not equal to, etc.&lt;/p&gt;

&lt;p&gt;However, in JavaScript, ALL variables themselves are inherently true/false - this is known as "truthiness", and you can view the full table here: &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Truthy"&gt;https://developer.mozilla.org/en-US/docs/Glossary/Truthy&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Where this becomes problematic is that it's SO easy to misuse this or have subtle errors in your code. In other languages, if you put a string inside of an &lt;code&gt;if&lt;/code&gt; statement, you'll get a compile error, since it's not a boolean expression. In JavaScript though, you can do this without any errors at all - not even at runtime. Instead, every value is "coerced" to boolean. And, the rules aren't always intuitive.&lt;/p&gt;

&lt;p&gt;The important thing to remember is that ONLY the following values evaluate to &lt;code&gt;false&lt;/code&gt; - ALL others evaluate to &lt;code&gt;true&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;false&lt;/li&gt;
&lt;li&gt;0&lt;/li&gt;
&lt;li&gt;-0&lt;/li&gt;
&lt;li&gt;0n (BigInt 0)&lt;/li&gt;
&lt;li&gt;"" (empty string)&lt;/li&gt;
&lt;li&gt;null&lt;/li&gt;
&lt;li&gt;undefined&lt;/li&gt;
&lt;li&gt;NaN (not a number)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Frankly, this list doesn't look all that bad. It kind of makes sense (don't get me started on &lt;code&gt;-0&lt;/code&gt; (negative zero) - that just has danger written all over it), but having an empty string evaluate to false sort of makes sense. What doesn't make sense, however, is that an empty array &lt;code&gt;[]&lt;/code&gt; evaluates to &lt;code&gt;true&lt;/code&gt;. C'mon guys - if you're going to have a very flexible/dynamic type system, at least make it consistent! Arrays and strings can both be &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt; - so why is an empty string treated differently from an empty array?&lt;/p&gt;

&lt;p&gt;The answer lies in a subtlety of the JavaScript language - strings are a special type, while arrays are objects. In JavaScript, all object references (as long as they aren't &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt;) evaluate to &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Anyways, as you may have gathered by now, I experienced this exact problem, where I was expecting an empty array to be &lt;code&gt;false&lt;/code&gt;, but it was in fact &lt;code&gt;true&lt;/code&gt;, and it took me running a unit test through a debugger to figure it out.&lt;/p&gt;

&lt;p&gt;The moral of the story is, if you're unfamiliar/new to a particular language, make sure you carefully read (and re-read) the documentation, and always challenge your assumptions when debugging.&lt;/p&gt;

&lt;p&gt;What are your favorite JavaScript "Truthy" stories? Let me know in the comments!&lt;/p&gt;

&lt;p&gt;Interested in working with me in the awesome Digital Products team here at Accenture? We're hiring &lt;a href="https://www.accenture.com/us-en/careers/jobdetails?id=00960587_en&amp;amp;title=Native+Mobile+Developer"&gt;native mobile developers&lt;/a&gt;, &lt;a href="https://www.accenture.com/us-en/careers/jobdetails?id=00960583_en&amp;amp;title=Hybrid+Mobile+Developer"&gt;hybrid mobile developers&lt;/a&gt;, &lt;a href="https://www.accenture.com/us-en/careers/jobdetails?id=00906120_en&amp;amp;title=Web+Developer"&gt;web developers&lt;/a&gt;, and &lt;a href="https://www.accenture.com/us-en/careers/jobsearch?jk=%22Digital%20Products%22&amp;amp;sb=0&amp;amp;pg=1&amp;amp;is_rj=0&amp;amp;ct=ma%20-%20cambridge%7Cny%20-%20new%20york"&gt;more&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>mattstidbits</category>
      <category>javascript</category>
      <category>tidbittuesday</category>
    </item>
    <item>
      <title>Matt's Tidbits #97 - Running/Debugging individual Jest unit tests</title>
      <dc:creator>Matthew Groves</dc:creator>
      <pubDate>Tue, 01 Jun 2021 14:16:06 +0000</pubDate>
      <link>https://forem.com/mpeng3/matt-s-tidbits-97-running-debugging-individual-jest-unit-tests-475k</link>
      <guid>https://forem.com/mpeng3/matt-s-tidbits-97-running-debugging-individual-jest-unit-tests-475k</guid>
      <description>&lt;p&gt;&lt;a href="https://medium.com/nerd-for-tech/matts-tidbits-96-cleaner-components-with-react-fragments-aef93ffdf18c"&gt;Last week I wrote about React Fragments.&lt;/a&gt; This week, I have a quick tidbit about running tests in VS Code.&lt;/p&gt;

&lt;p&gt;I hope you all had a restful long weekend! &lt;a href="https://matthew-b-groves.medium.com/matts-tidbits-81-the-importance-of-vacation-fcff932cda71"&gt;I've written about the importance of vacation before&lt;/a&gt;, and in this pandemic that just seems to keep on going (although hopefully we're starting to see the end), it's more important now than ever to prioritize your health and take care of yourself!&lt;/p&gt;

&lt;p&gt;As you may have noticed, since I've been writing about it a bunch recently, my current project is using React Native. We're using &lt;a href="https://jestjs.io"&gt;Jest&lt;/a&gt; for our unit tests, and it's a pretty decent tool. However, it caught me slightly by surprise that the only way (that I knew of) to run our tests was via a &lt;code&gt;yarn test&lt;/code&gt; command that ran them all at once. This became especially troublesome when I had to debug a failing unit test (perhaps I'll write about that next time), and was trying to find a way to shorten my write/test cycle.&lt;/p&gt;

&lt;p&gt;Thankfully, one of my coworkers pointed me at a VERY helpful VS Code extension: &lt;a href="https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner"&gt;https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This extension provides links next to each unit test to let you run or debug them individually! If you're using Jest &amp;amp; VS Code, you really MUST download this extension - I guarantee you it will come in handy!&lt;/p&gt;

&lt;p&gt;What are your favorite VS Code extensions? Let me know in the comments below!&lt;/p&gt;

&lt;p&gt;Interested in working with me in the awesome Digital Products team here at Accenture? &lt;a href="https://www.accenture.com/us-en/careers/jobsearch?jk=%22Digital%20Products%22&amp;amp;sb=0&amp;amp;pg=1&amp;amp;is_rj=0"&gt;We're hiring!&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mattstidbits</category>
      <category>reactnative</category>
      <category>jest</category>
      <category>tidbittuesday</category>
    </item>
    <item>
      <title>Matt's Tidbits #96 - Cleaner Components with React Fragments</title>
      <dc:creator>Matthew Groves</dc:creator>
      <pubDate>Tue, 25 May 2021 12:17:21 +0000</pubDate>
      <link>https://forem.com/mpeng3/matt-s-tidbits-96-cleaner-components-with-react-fragments-3hh2</link>
      <guid>https://forem.com/mpeng3/matt-s-tidbits-96-cleaner-components-with-react-fragments-3hh2</guid>
      <description>&lt;p&gt;&lt;a href="https://medium.com/nerd-for-tech/matts-tidbits-95-defining-constants-in-typescript-1a74d00b08a1"&gt;Last time, I wrote about defining constants in TypeScript.&lt;/a&gt; This week, I want to share what I learned about React Fragments!&lt;/p&gt;

&lt;p&gt;To many of my readers who are Android developers, you already know all about Fragments from the standpoint of building Android UI. However, in the React/React Native world, Fragments serve an entirely different purpose.&lt;/p&gt;

&lt;p&gt;First, an example — say you want to define a method (or component) that returns some elements, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Stack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createStackNavigator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SomeComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Navigator&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;getScreens&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Stack.Navigator&lt;/span&gt;&lt;span class="err"&gt;&amp;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;A likely first implementation of &lt;code&gt;getScreens()&lt;/code&gt; would return an array (at least, this is how I did this at first):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getScreens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Screen&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Screen1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Screen1Component&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;,
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Screen&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Screen2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Screen2Component&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&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;Unfortunately, this approach will yield a compiler warning:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Warning: Each child in a list should have a unique "key" prop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://reactjs.org/docs/lists-and-keys.html"&gt;The reason for this is that React dictates that every element in a list must have a uniquely identifiable “key” property&lt;/a&gt; — largely to assist in comparing two versions of the same list — were new elements added, were some elements removed, or did existing elements change position in the list? This is a great feature, but in the case of our list of Screens, it’s somewhat redundant to have to define a “key” property on each item. We already have a unique “key” (the &lt;code&gt;name&lt;/code&gt; field), and besides, we’re not expecting this list to change over time.&lt;/p&gt;

&lt;p&gt;Thankfully, React provides a cleaner solution to this very problem — &lt;a href="https://reactjs.org/docs/fragments.html"&gt;Fragments&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Here’s what &lt;code&gt;getScreens()&lt;/code&gt; would look like if we use a Fragment instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getScreens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Fragment&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Screen&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Screen1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Screen1Component&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Screen&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Screen2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Screen2Component&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/React.Fragment&lt;/span&gt;&lt;span class="err"&gt;&amp;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;Voilà! This works just as well, we don’t have to add commas to the end of each line, and, most importantly, we don’t need to define a “key” property on each item.&lt;/p&gt;

&lt;p&gt;There’s one more neat shorthand you can use, and that is to replace &lt;code&gt;&amp;lt;React.Fragment&amp;gt;&lt;/code&gt; with the short syntax &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt; to further clean this up and make it clear that the Fragment is really just a wrapper.&lt;/p&gt;

&lt;p&gt;An alternative approach would be to wrap elements within a React &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; or React Native &lt;code&gt;&amp;lt;View&amp;gt;&lt;/code&gt; element, however, this has a few drawbacks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You’re actually adding an additional item to the view hierarchy — Fragments disappear during the rendering process.&lt;/li&gt;
&lt;li&gt;Some scenarios, like the React Navigation example above, will not allow for any element other than a &lt;code&gt;&amp;lt;Stack.Screen&amp;gt;&lt;/code&gt; to be embedded directly within a &lt;code&gt;&amp;lt;Stack.Navigator&amp;gt;&lt;/code&gt; — leaving Fragments as the only viable option.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope you learned something useful about Fragments that will help improve your React code! Do you use Fragments in other/unique ways? I’d love to hear about it in the comments!&lt;/p&gt;

&lt;p&gt;Interested in working with me in the awesome Digital Products team here at Accenture? &lt;a href="https://www.accenture.com/us-en/careers/jobsearch?jk=%22Digital%20Products%22&amp;amp;sb=0&amp;amp;pg=1&amp;amp;is_rj=0"&gt;We’re hiring!&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mattstidbits</category>
      <category>react</category>
      <category>reactnative</category>
      <category>tidbittuesday</category>
    </item>
    <item>
      <title>Matt's Tidbits #95 - Defining constants in TypeScript</title>
      <dc:creator>Matthew Groves</dc:creator>
      <pubDate>Tue, 11 May 2021 12:13:29 +0000</pubDate>
      <link>https://forem.com/mpeng3/matt-s-tidbits-95-defining-constants-in-typescript-1163</link>
      <guid>https://forem.com/mpeng3/matt-s-tidbits-95-defining-constants-in-typescript-1163</guid>
      <description>&lt;p&gt;&lt;a href="https://medium.com/nerd-for-tech/matts-tidbits-94-writing-safe-enums-in-typescript-2955706a1e5c"&gt;Last time I wrote about how to write safe enums in TypeScript.&lt;/a&gt; This week's tidbit is also TypeScript related - how to define constants!&lt;/p&gt;

&lt;p&gt;Defining a constant in TypeScript can be pretty simple - you can just write something like &lt;code&gt;const SOME_CONSTANT="FOO";&lt;/code&gt;. However, that &lt;code&gt;const&lt;/code&gt; keyword only works if you're defining variables at file-scope or inside a function. What if you want to group your constants under some kind of named object (as is common in other languages such as Java, C++, etc.)&lt;/p&gt;

&lt;p&gt;The obvious way (and what I did to start), was simply to define an object to contain my constants, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;NamedVariables&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;SOME_CONSTANT_1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;FOO&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;SOME_CONSTANT_2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;DEFAULT_FONT_WEIGHT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;700&lt;/span&gt;&lt;span class="dl"&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;This allows me to use this like this: &lt;code&gt;NamedVariables.SOME_CONSTANT_1&lt;/code&gt;. Great!&lt;/p&gt;

&lt;p&gt;However, there's one tiny gotcha. This works fine for some situations, but in cases where TypeScript is expecting a value that's part of a union type, such as specifying the &lt;code&gt;fontWeight&lt;/code&gt; property of a React Native &lt;code&gt;TextStyle&lt;/code&gt;, you may see an error such as this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Type 'string' is not assignable to type '"normal" | "bold" | "100" | "200" | "300" | "400" | "500" | "600" | "700" | "800" | "900" | undefined'.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're like me, you might scratch your head over this for quite a while. Until you realize (do some fervent Google searching) that Object properties are not constant by default.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;const&lt;/code&gt; in &lt;code&gt;const NamedVariables&lt;/code&gt; above means that the reference to that object is constant - so it would be illegal to do something like &lt;code&gt;NamedVariables = &amp;lt;something else&amp;gt;&lt;/code&gt; after it's already been defined. Which is good - we definitely don't want someone to reassign our constants object. But how can we define its properties as constant?&lt;/p&gt;

&lt;p&gt;The first thing I found is to use &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze"&gt;&lt;code&gt;Object.freeze()&lt;/code&gt;&lt;/a&gt; - this returns an object whose properties are read-only. So, if we try this with our example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;NamedVariables&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;SOME_CONSTANT_1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;FOO&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;SOME_CONSTANT_2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;DEFAULT_FONT_WEIGHT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;700&lt;/span&gt;&lt;span class="dl"&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;Unfortunately, this STILL doesn't work if we try to use &lt;code&gt;DEFAULT_FONT_WEIGHT&lt;/code&gt; in a union type. Why is this? As best as I can understand, it's because TypeScript doesn't recognize this as a true constant - Object.freeze() makes use of some somewhat crazy runtime checks that throw an error if you try to modify it. So, chalk this one up to a limitation (maybe temporary? maybe permanent?) of TypeScript.&lt;/p&gt;

&lt;p&gt;So… is there any way to achieve this? The good news is, yes!&lt;/p&gt;

&lt;p&gt;Here's how we can make all properties on an object be treated as constants:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;NamedVariables&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;SOME_CONSTANT_1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;FOO&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;SOME_CONSTANT_2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;DEFAULT_FONT_WEIGHT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;700&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/b&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it - those two little keywords at the end &lt;a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions"&gt;&lt;code&gt;as const&lt;/code&gt;&lt;/a&gt; - are a TypeScript addition (not part of JavaScript) that instruct the type checker that all properties on that object should be treated as constants.&lt;/p&gt;

&lt;p&gt;I highly recommend adding this to all of your Objects that you intend to be constants. Let the type system help you!&lt;/p&gt;

&lt;p&gt;Do you define constants differently? I'd love to hear from you in the comments!&lt;/p&gt;

&lt;p&gt;Interested in working with me in the awesome Digital Products team here at Accenture? &lt;a href="https://www.intrepid.io/careers"&gt;We're hiring!&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mattstidbits</category>
      <category>typescript</category>
      <category>tidbittuesday</category>
    </item>
    <item>
      <title>Matt's Tidbits #94 - Writing safe enums in TypeScript</title>
      <dc:creator>Matthew Groves</dc:creator>
      <pubDate>Tue, 27 Apr 2021 21:08:32 +0000</pubDate>
      <link>https://forem.com/mpeng3/matt-s-tidbits-94-writing-safe-enums-in-typescript-5gf4</link>
      <guid>https://forem.com/mpeng3/matt-s-tidbits-94-writing-safe-enums-in-typescript-5gf4</guid>
      <description>&lt;p&gt;&lt;a href="https://medium.com/nerd-for-tech/matts-tidbits-93-getting-started-with-react-native-acdec42c67f"&gt;Last time I wrote about how to get started with React Native.&lt;/a&gt; This week, I have a quick tidbit about writing safe enums in TypeScript!&lt;/p&gt;

&lt;p&gt;Many programming languages have support for enums, but they work slightly differently in TypeScript.&lt;/p&gt;

&lt;p&gt;It’s really simple to define and use an enum — you can do so like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;MyEnum&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;enum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MyEnum&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MyEnum&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;A&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What really surprised me is that it’s also perfectly valid to do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WHY?!!? To be honest, this really makes no sense to me at all. If I’ve gone through all the trouble of defining an enum (and specifying an enum as a parameter to a function), why can I specify any arbitrary number in place of this enum and have it still be valid code?&lt;/p&gt;

&lt;p&gt;&amp;lt;5 minute meditation break/&amp;gt;&lt;/p&gt;

&lt;p&gt;The good news is, there’s a way to guarantee that your enums cannot be used in this way!&lt;/p&gt;

&lt;p&gt;As in many other programming languages, enums are typically represented as integers — the first enum value is equivalent to 0, the second is 1, etc. However, TypeScript has support for two other types of enums: string-based and heterogeneous enums.&lt;/p&gt;

&lt;p&gt;Unfortunately, heterogeneous enums suffer from the same problem as numeric enums. But, string-based enums do not!&lt;/p&gt;

&lt;p&gt;So, if you change your enum definition to look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;MyEnum&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;B&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;B&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;C&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;C&lt;/span&gt;&lt;span class="dl"&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;Now the only way to call our &lt;code&gt;foo&lt;/code&gt; function is by passing one of the valid enum values — passing arbitrary numbers (or strings) will produce the following compile error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Argument of type '42' is not assignable to parameter of type 'MyEnum'.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There may be cases where you want to be able to specify arbitrary numeric values for enums, but I will be sticking to the string-based version!&lt;/p&gt;

&lt;p&gt;For more information on enums in TypeScript, check out the official handbook: &lt;a href="https://www.typescriptlang.org/docs/handbook/enums.html"&gt;https://www.typescriptlang.org/docs/handbook/enums.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If anyone knows why TypeScript enums were designed with this behavior, please let me know in the comments!&lt;/p&gt;

&lt;p&gt;Interested in working with me in the awesome Digital Products team here at Accenture? &lt;a href="https://www.intrepid.io/careers"&gt;We’re hiring!&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mattstidbits</category>
      <category>typescript</category>
      <category>tidbittuesday</category>
    </item>
    <item>
      <title>Matt's Tidbits #93 - Getting started with React Native</title>
      <dc:creator>Matthew Groves</dc:creator>
      <pubDate>Tue, 06 Apr 2021 14:16:00 +0000</pubDate>
      <link>https://forem.com/mpeng3/matt-s-tidbits-93-getting-started-with-react-native-31j8</link>
      <guid>https://forem.com/mpeng3/matt-s-tidbits-93-getting-started-with-react-native-31j8</guid>
      <description>&lt;p&gt;&lt;a href="https://medium.com/nerd-for-tech/matts-tidbits-92-a-few-neat-ide-tidbits-9222a69be53f"&gt;Last time I shared a few IDE-related tidbits.&lt;/a&gt; This week, I have some quick tidbits on getting started with React Native!&lt;/p&gt;

&lt;p&gt;My latest project is using React Native (with TypeScript), so I've been doing a lot of studying and preparation.&lt;/p&gt;

&lt;p&gt;One of the tutorials I went through had me set up a fresh project using React Native's TypeScript template. Unfortunately, I discovered that it wouldn't build for iOS! After a little searching, it turns out there's a known issue: &lt;a href="https://github.com/facebook/react-native/issues/30836"&gt;https://github.com/facebook/react-native/issues/30836&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my sample project, I took the approach of commenting out the "Flipper" dependency, which allowed the app to build successfully.&lt;/p&gt;

&lt;p&gt;I know React Native gets a lot of bad press, but in my opinion, the underlying principles modeled in React (unidirectional data flow, etc.) are awesome, and native Android development could benefit a lot from using patterns like this! If you're interested in learning more, this "Thinking in React" article from the official React website (and the rest of their "Main Concepts" documentation) were especially helpful: &lt;a href="https://reactjs.org/docs/thinking-in-react.html"&gt;https://reactjs.org/docs/thinking-in-react.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As an Android developer, I haven't had many reasons to use Xcode before, but I'm excited by the idea of getting to develop for iOS (I've been an Apple fan for the past 25+ years). I did run into one issue (at least on my somewhat locked-down work laptop) - the standard instructions of installing Cocoa Pods via the &lt;code&gt;gem&lt;/code&gt; command didn't work for me. But, I was able to get it working by installing them via &lt;code&gt;brew&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It's also important to make sure the Xcode Command Line Tools path is set in Xcode-&amp;gt;Preferences-&amp;gt;Locations. If it's not, you won't be able to build iOS apps in React Native!&lt;/p&gt;

&lt;p&gt;Have any other helpful tidbits for someone getting started with React Native? Let me know in the comments!&lt;/p&gt;

&lt;p&gt;Interested in working with me in the awesome Digital Products team here at Accenture? &lt;a href="https://www.intrepid.io/careers"&gt;We're hiring!&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mattstidbits</category>
      <category>reactnative</category>
      <category>tidbittuesday</category>
    </item>
    <item>
      <title>Matt's Tidbits #92 - A few neat IDE tidbits</title>
      <dc:creator>Matthew Groves</dc:creator>
      <pubDate>Tue, 23 Mar 2021 14:18:31 +0000</pubDate>
      <link>https://forem.com/mpeng3/matt-s-tidbits-92-a-few-neat-ide-tidbits-561g</link>
      <guid>https://forem.com/mpeng3/matt-s-tidbits-92-a-few-neat-ide-tidbits-561g</guid>
      <description>&lt;p&gt;&lt;a href="https://medium.com/nerd-for-tech/matts-tidbits-91-the-power-of-sharing-31e5407d456c"&gt;In my last post, I wrote about the RxJava share operator.&lt;/a&gt; This week, I have a few quick IDE tidbits!&lt;/p&gt;

&lt;p&gt;I've written about some fun IDE plugins before in &lt;a href="https://matthew-b-groves.medium.com/matts-tidbits-6-useful-android-studio-plugins-bb67fe640c89"&gt;Tidbit #6&lt;/a&gt;, but I recently got a new work laptop, and in the process of reinstalling Android Studio discovered a new one!&lt;/p&gt;

&lt;p&gt;Previously I had been using the &lt;a href="https://plugins.jetbrains.com/plugin/8575-nyan-progress-bar"&gt;NyanCat progress bar&lt;/a&gt; (because work should be fun!), but when I found out there's a MARIO PROGRESS BAR I knew I needed to check it out:&lt;br&gt;
&lt;a href="https://plugins.jetbrains.com/plugin/14708-mario-progress-bar"&gt;https://plugins.jetbrains.com/plugin/14708-mario-progress-bar&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If Mario isn't your thing, that's ok - there are a LOT of different options, depending on your preferences:&lt;br&gt;
&lt;a href="https://plugins.jetbrains.com/search?search=progress%20bar"&gt;https://plugins.jetbrains.com/search?search=progress%20bar&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;I alluded to multiple tidbits in the title of this article, so hopefully you're still with me! My next project is going to be written in React Native, so I have been refreshing my JavaScript and learning all about the new frameworks. Part of the change means leaving the familiar confines of Android Studio for other editors - in this case, Visual Studio Code.&lt;/p&gt;

&lt;p&gt;I've used Visual Studio before at a previous job, and VS Code is a fine editor, but I've really gotten used to working in Android Studio. For me, part of the biggest challenge of switching development languages is changing tools.&lt;/p&gt;

&lt;p&gt;The good news is, I discovered a plugin for VS Code that applies many of Android Studio's keyboard shortcuts to VS Code! You can find it here: &lt;a href="https://github.com/kasecato/vscode-intellij-idea-keybindings"&gt;https://github.com/kasecato/vscode-intellij-idea-keybindings&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm still refreshing my JavaScript skills, learning TypeScript, and getting used to programming in a dynamically-typed language (that's the &lt;em&gt;real&lt;/em&gt; challenge), but being able to navigate in the editor in a way I'm used to has been very helpful thus far.&lt;/p&gt;

&lt;p&gt;This type of plugin is available for many other different editors. So, if you're moving to a new project, and aren't comfortable with the tools, see if there's a keymapping plugin that will make the editor behave like one you already know!&lt;/p&gt;

&lt;p&gt;Two questions this time:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What editor has your favorite keybindings? (Not your favorite editor per-se - I'm not trying to start a vi vs. emacs war)&lt;/li&gt;
&lt;li&gt;What is your preferred progress bar for Android Studio? Standard? Nyan Cat? Mario? Something else?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let me know in the comments!&lt;/p&gt;

&lt;p&gt;Interested in working with me in the awesome Digital Products team here at Accenture? &lt;a href="https://www.intrepid.io/careers"&gt;We're hiring!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;These tidbits were discovered on March 10, 2021.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mattstidbits</category>
      <category>android</category>
      <category>vscode</category>
      <category>tidbittuesday</category>
    </item>
  </channel>
</rss>
