<?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: Luke Mueller</title>
    <description>The latest articles on Forem by Luke Mueller (@lukemueller).</description>
    <link>https://forem.com/lukemueller</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%2F306482%2F9ed1e328-640a-497e-9b9e-bb833cd91007.jpeg</url>
      <title>Forem: Luke Mueller</title>
      <link>https://forem.com/lukemueller</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/lukemueller"/>
    <language>en</language>
    <item>
      <title>Pro Tip: cd for macOS Finder</title>
      <dc:creator>Luke Mueller</dc:creator>
      <pubDate>Sat, 23 Jan 2021 00:30:15 +0000</pubDate>
      <link>https://forem.com/focused_dot_io/pro-tip-cd-for-macos-finder-4fdc</link>
      <guid>https://forem.com/focused_dot_io/pro-tip-cd-for-macos-finder-4fdc</guid>
      <description>&lt;p&gt;⌘+⇧+g&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzqc283hs12l8uurwkrxa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzqc283hs12l8uurwkrxa.png" alt="cd for macOS Finder" width="800" height="327"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>AndroidX, LiveData and the Observable Pattern</title>
      <dc:creator>Luke Mueller</dc:creator>
      <pubDate>Mon, 27 Jan 2020 19:39:53 +0000</pubDate>
      <link>https://forem.com/focused_dot_io/androidx-livedata-and-the-observable-pattern-1i9l</link>
      <guid>https://forem.com/focused_dot_io/androidx-livedata-and-the-observable-pattern-1i9l</guid>
      <description>&lt;h3&gt;
  
  
  Android has come a loooong way
&lt;/h3&gt;

&lt;p&gt;I was really pleased when returning to Android development after being away for a while at how much better it has gotten with AndroidX. Now this isn’t breaking news to most, but Android Jetpack and the &lt;code&gt;androidx.*&lt;/code&gt; package libraries not only solved one of the most confusing aspects of Android development ( those pesky versioned Android Support Libraries ) but also brought the observable pattern front and center with &lt;code&gt;LiveData&lt;/code&gt; and &lt;code&gt;ViewModel&lt;/code&gt;. While LiveData is not quite as robust or generic as RxJava, it is effectively a basic implementation of the Observable pattern with the added benefit of being &lt;strong&gt;Lifecycle Aware&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That last bit there is huge. Being lifecycle aware means that you don’t have to worry about memory leaks or hard-to-debug NPEs because your observables live and die with their observers. Activities and their layouts go in and out of memory as user's navigate around. Ensuring that our asynchronous data loads don't try and update screens long gone is especially important.&lt;/p&gt;

&lt;h3&gt;
  
  
  It’s all about the &lt;code&gt;observe&lt;/code&gt; method.
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;public void observe(@NonNull LifecycleOwner owner, @NonNull Observer&amp;lt;? super T&amp;gt; observer);&lt;/code&gt; takes two parameters: an owner with a Lifecycle and an Observer for trigger when the underlying value changes. Pretty straightforward.&lt;/p&gt;

&lt;p&gt;Coupling this with Android’s &lt;code&gt;Data Binding Library&lt;/code&gt; means screens that handling swiping full screen content layouts is a really clean and pleasant exercise. One of our latest client projects involved adding the capability for their customers to take the physical gift cards purchased in their stores and add them to a digital wallet. We wanted to build a way for customers to be able to view all the details of an individual card (card number, barcode, terms and conditions, transaction history, etc..) We decided that a full screen view of each card was required for all this information but wanted users to be able to swipe left and right to horizontally page between each of the cards in their wallet.&lt;/p&gt;

&lt;p&gt;We decided to effectively use a &lt;code&gt;ViewPager&lt;/code&gt; and &lt;code&gt;PagerAdapter&lt;/code&gt; to accomplish the horizontal paging between gift cards. That, combined with a &lt;code&gt;ViewModel&lt;/code&gt; to track the current page meant that the our observe callback just had to update the data binding backing the view after loading from our API.&lt;/p&gt;

&lt;p&gt;Here is a simplified example of the Activity:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GiftCardDetailsActivity&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;AppCompatActivity&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;GiftCardDetailsPagerListener&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;GiftCardsDetailViewModel&lt;/span&gt; &lt;span class="n"&gt;giftCardsViewModel&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;GiftCardDetailsActivityBinding&lt;/span&gt; &lt;span class="n"&gt;binding&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;GiftCardTransactionAdapter&lt;/span&gt; &lt;span class="n"&gt;giftCardTransactionAdapter&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Bundle&lt;/span&gt; &lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onCreate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;initialPosition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;getIntent&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getSerializableExtra&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;GIFT_CARD_INITIAL_POSITION_EXTRA&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;giftCardsViewModel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ViewModelProviders&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;GiftCardsDetailViewModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;giftCardTransactionAdapter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GiftCardTransactionAdapter&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;binding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DataBindingUtil&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setContentView&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;R&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;gift_card_details_activity&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;binding&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;giftCardViewPager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setAdapter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GiftCardDetailsPagerAdapter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;initialPosition&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;giftCardsViewModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getCurrentGiftCard&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;observe&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;currentGiftCard&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;binding&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setGiftCard&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;currentGiftCard&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;binding&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;barcodeImage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setImageBitmap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BarcodeGenerator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;generateBarcodeImage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;getResources&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;currentGiftCard&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getNumber&lt;/span&gt;&lt;span class="o"&gt;()));&lt;/span&gt;
            &lt;span class="n"&gt;giftCardTransactionAdapter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setGiftCardTransactions&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;currentGiftCard&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getTransactions&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
            &lt;span class="n"&gt;giftCardTransactionAdapter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;notifyDataSetChanged&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;});&lt;/span&gt;

        &lt;span class="n"&gt;giftCardsViewModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setCurrentGiftCardPosition&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;initialPosition&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;onPageSelected&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;giftCardsViewModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setCurrentGiftCardPosition&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;And the ViewModel:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GiftCardsDetailViewModel&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;AsyncLoadingViewModel&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;GiftCardsApiResponseListener&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;GiftCardApiService&lt;/span&gt; &lt;span class="n"&gt;giftCardApiService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;MutableLiveData&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;GiftCard&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;currentGiftCard&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MutableLiveData&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GiftCard&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;GiftCard&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;giftCards&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;initialPosition&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nc"&gt;LiveData&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;GiftCard&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getCurrentGiftCard&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;giftCards&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;setIsLoading&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;giftCardsApiService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fetch&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;currentGiftCard&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setCurrentGiftCardPosition&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;giftCards&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;position&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;giftCards&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="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;initialPosition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;currentGiftCard&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;giftCards&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;onGiftCardsApiResponseSuccess&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;GiftCard&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;giftCards&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;setIsLoading&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;giftCards&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;giftCards&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentGiftCard&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;giftCards&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;initialPosition&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;onGiftCardsApiResponseFailure&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;errorMessage&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;setIsLoading&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// classic "error handling here" blog post comment...&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;On of the nice things about this implementation is that there is only one way, and exactly one way, in which data is set on the view binding. Our Activity’s &lt;code&gt;onCreate()&lt;/code&gt; is responsible for instantiating the &lt;code&gt;ViewModel&lt;/code&gt; that tracks the current page, and holds onto the full list of gift cards that are asynchronously loaded from our server’s API. Anytime the instance of the &lt;code&gt;ViewModel&lt;/code&gt;’s underlying &lt;code&gt;LiveData&lt;/code&gt; member's change, our observable callback is triggered and we simply update the bindings gift card. Notice that the first argument to the &lt;code&gt;observe()&lt;/code&gt; call is an implementation of &lt;code&gt;LifecycleAware&lt;/code&gt;. In this case, our Activity itself.&lt;/p&gt;

&lt;p&gt;A few other noteworthy details:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;While our ViewModel's private member &lt;code&gt;currentGiftCard&lt;/code&gt; is of type &lt;code&gt;MutableLiveData&lt;/code&gt; we only expose &lt;code&gt;LiveData&lt;/code&gt; to observers. This is important because it isolates the responsibility of managing that state to our &lt;code&gt;ViewModel&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;AsyncLoadingViewModel&lt;/code&gt; is just a parent class that extends Android's &lt;code&gt;ViewModel&lt;/code&gt; class and manages a single piece of state for loading masks of type &lt;code&gt;LiveData&amp;lt;Boolean&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;ViewModel&lt;/code&gt; holds onto the initial position until the initial data load is completed.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Followup
&lt;/h3&gt;

&lt;p&gt;I should note here that there are a few other ways to accomplish similar behavior by leveraging more of the AndroidX library, including &lt;code&gt;Two-way data binding&lt;/code&gt;, &lt;code&gt;@BindingAdapters&lt;/code&gt;, and &lt;code&gt;BaseObservables&lt;/code&gt;. Given we are not taking any user input on these largely view-only screens, this felt like overkill. This simple pattern seemed to work well for the initial version of these screens.&lt;/p&gt;

&lt;p&gt;Perhaps a follow-up post to compare / contrast is in order!&lt;/p&gt;

</description>
      <category>android</category>
      <category>java</category>
    </item>
    <item>
      <title>Scratching the surface of composition with React Native and Apollo</title>
      <dc:creator>Luke Mueller</dc:creator>
      <pubDate>Thu, 02 Jan 2020 15:27:34 +0000</pubDate>
      <link>https://forem.com/focused_dot_io/scratching-the-surface-of-composition-with-react-native-and-apollo-3j7k</link>
      <guid>https://forem.com/focused_dot_io/scratching-the-surface-of-composition-with-react-native-and-apollo-3j7k</guid>
      <description>&lt;p&gt;When I first stumbled upon Andrew Clark's &lt;a href="https://github.com/acdlite/recompose" rel="noopener noreferrer"&gt;&lt;code&gt;recompose&lt;/code&gt;&lt;/a&gt; library I thought awesome, I'm always up for some composition! However, a quick glance at the docs left me feeling like there was a large learning curve ahead of me as I was still just getting comfortable with React Native and GraphQL.&lt;/p&gt;

&lt;p&gt;In this post I'll share a few recipes that helped me get started with &lt;code&gt;recompose&lt;/code&gt; that had a high degree of impact of the quality of my code. The code examples below are from a project I've been working on called &lt;a href="https://broce.com/" rel="noopener noreferrer"&gt;Broce&lt;/a&gt;. &lt;br&gt;
At a high level, the tech stack is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React Native&lt;/li&gt;
&lt;li&gt;Expo&lt;/li&gt;
&lt;li&gt;React Apollo&lt;/li&gt;
&lt;li&gt;GraphQL backend in Ruby/Rails&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  On the Menu today
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Starter:&lt;/strong&gt; Factor out reusable logic with pure, composable functions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Main Course:&lt;/strong&gt; Factor out fetching remote data from our component all together&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dessert:&lt;/strong&gt; Convert our component to a React PureComponent&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Tasting Notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;This article assumes you have experience with React and GraphQL&lt;/li&gt;
&lt;li&gt;Are familiar with or have dappled in composition and higher-order functions
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Let's eat!
&lt;/h2&gt;

&lt;p&gt;If you follow the React and Apollo docs you'll quickly end up with a component that looks like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;COMPANY_QUERY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt;&lt;span class="s2"&gt;`{
  company {
    name
    website
  }
}`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CompanyScreen&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;render&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;Query&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{({&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;LoadingMask&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ErrorScreen&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="o"&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="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;ScrollView&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;CompanyForm&lt;/span&gt; &lt;span class="nx"&gt;company&lt;/span&gt;&lt;span class="o"&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;/ScrollView&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;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Query&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This component has a few responsibilities:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It extends a &lt;code&gt;React.Component&lt;/code&gt; and is responsible for rendering the component's layout&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;CompanyScreen&lt;/code&gt;'s render element is wrapped by Apollo's &lt;code&gt;Query&lt;/code&gt; component so that it can fetch data from the GraphQL server&lt;/li&gt;
&lt;li&gt;It handles the loading and error states for the respective GraphQL query&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It's fair to say that Uncle Bob would have an opinion about such a component. We're violating the Single Responsibility Principle a few times over. My main issue with Apollo's &lt;code&gt;Query&lt;/code&gt; wrapping component is that it couples the concern of fetching remote data with display logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Appetizer
&lt;/h2&gt;

&lt;p&gt;Our first step is to factor away those 2 &lt;code&gt;if&lt;/code&gt; conditions that deal with loading and error states. I had been copy and pasting that code around and could easily imagine scenarios where that logic would get more complex (think different error types that warrant different handlers).&lt;/p&gt;

&lt;p&gt;We can create 2 plain old javascript constants which leverage recompose's &lt;code&gt;branch&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;displayLoadingState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;branch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nf"&gt;renderComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;LoadingMask&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;displayErrorState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;branch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nf"&gt;renderComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ErrorScreen&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;The &lt;code&gt;branch&lt;/code&gt; function takes 3 arguments. The first is a &lt;code&gt;test&lt;/code&gt; function, the second and third arguments are the potential return components if the &lt;code&gt;test&lt;/code&gt; functions returns either true or false. Really, it's just another way to go about an if/else condition.&lt;/p&gt;

&lt;p&gt;Our test functions look at the component's Apollo provided props and checks if the &lt;code&gt;data.loading&lt;/code&gt; or &lt;code&gt;data.error&lt;/code&gt; states are set. In that event that the query is loading or returned an error, we call recompose's &lt;br&gt;
&lt;code&gt;renderComponent&lt;/code&gt; function, passing it our beautifully styled LoadingMask and ErrorScreen components. In the falsey case, we do nothing as we want our CompanyScreen component to render.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A litter further down we'll see how recompose manages to pass the component's props to the &lt;code&gt;test&lt;/code&gt; functions above, for now let's just assume magic is real and the props will safely arrive&lt;/em&gt;   &lt;/p&gt;
&lt;h2&gt;
  
  
  Main course
&lt;/h2&gt;

&lt;p&gt;Now, let's go about removing that Apollo query logic from our &lt;code&gt;CompanyScreen&lt;/code&gt; component.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;react-apollo&lt;/code&gt; library offers a HOC function called &lt;code&gt;graphql&lt;/code&gt; which will allow us to avoid wrapping our screen components with &lt;code&gt;&amp;lt;Query /&amp;gt;&lt;/code&gt;. A Higher-Order-Component (HOC) is just a function that takes a component as an argument and returns a new component. All &lt;code&gt;recompose&lt;/code&gt; functions are just that, HOC component functions. We'll chain them together shortly.&lt;/p&gt;

&lt;p&gt;Introducing Apollo's &lt;code&gt;graphql&lt;/code&gt; HOC function will replace &lt;code&gt;&amp;lt;Query query=&amp;gt; ...&lt;/code&gt; with &lt;code&gt;graphql(COMPANY_QUERY)&lt;/code&gt;. This will be the first function passed to our composable component chain. Apollo will take and execute that query, returning a new component whose props receive Apollo's &lt;code&gt;data&lt;/code&gt; object.&lt;/p&gt;

&lt;p&gt;We've managed to factor away a lot of functionality but need to stitch it all back up.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CompanyScreen&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;render&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="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&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;ScrollView&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;CompanyForm&lt;/span&gt; &lt;span class="nx"&gt;company&lt;/span&gt;&lt;span class="o"&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;/ScrollView&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;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;compose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nf"&gt;graphql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;COMPANY_QUERY&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nx"&gt;displayLoadingState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;displayErrorState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nx"&gt;CompanyScreen&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can see a lot of code is gone from the &lt;code&gt;CompanyScreen&lt;/code&gt; component's render function. At the same time, we've introduced a new default export to this file. We no longer export the &lt;code&gt;CompanyScreen&lt;/code&gt; class itself, but rather we export the component that recompose's &lt;code&gt;compose&lt;/code&gt; function will create for us.&lt;/p&gt;

&lt;p&gt;The call to &lt;code&gt;compose&lt;/code&gt; at the bottom of the file will take multiple higher-order components and create a single HOC. This means our resulting &lt;code&gt;CompanyScreen&lt;/code&gt; component will have triggered our GraphQL query and Apollo will handle putting the ever important &lt;code&gt;data&lt;/code&gt; object onto its props. &lt;code&gt;recompose&lt;/code&gt; will also handle chaining the component's props as arguments to each one of the HOC functions passed to &lt;code&gt;compose&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Our CompanyScreen component now only has one concern, rendering a layout in the case of company data having been fetched. Uncle Bob would be proud.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dessert
&lt;/h2&gt;

&lt;p&gt;For desert we're going to convert our React component into a pure component, as it does not maintain any state. Only the declaration of the &lt;code&gt;CompanyScreen&lt;/code&gt; needs to change here. Rather than declaring it as a class we declare it as a function, one that receives and de-structures the props argument.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CompanyScreen&lt;/span&gt; &lt;span class="o"&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;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;ScrollView&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;CompanyForm&lt;/span&gt; &lt;span class="nx"&gt;company&lt;/span&gt;&lt;span class="o"&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;/ScrollView&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;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;compose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nf"&gt;graphql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;COMPANY_QUERY&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nx"&gt;displayLoadingState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;displayErrorState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nx"&gt;CompanyScreen&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>reactnative</category>
      <category>functional</category>
      <category>graphql</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
