<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Victor R.</title>
    <description>The latest articles on DEV Community by Victor R. (@crazedvic).</description>
    <link>https://dev.to/crazedvic</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%2F112539%2F19afb83b-f297-4757-8534-5c4fda760729.png</url>
      <title>DEV Community: Victor R.</title>
      <link>https://dev.to/crazedvic</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/crazedvic"/>
    <language>en</language>
    <item>
      <title>Dynamic Livewire Listeners</title>
      <dc:creator>Victor R.</dc:creator>
      <pubDate>Fri, 11 Feb 2022 20:10:34 +0000</pubDate>
      <link>https://dev.to/crazedvic/dynamic-livewire-listeners-3boi</link>
      <guid>https://dev.to/crazedvic/dynamic-livewire-listeners-3boi</guid>
      <description>&lt;p&gt;The challenge:  We have an unusually long list of items, displayed as cards on a single page.  We are using a modal to update those items.  On save, we only want that specific card to re-render.  We don't want nor need the whole list page (parent component to re-render).&lt;/p&gt;

&lt;p&gt;There are just a few livewire components in play here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Index component, which hosts the list of $items using a &lt;a class="mentioned-user" href="https://dev.to/foreach"&gt;@foreach&lt;/a&gt;, and displays an edit button next to each card&lt;/li&gt;
&lt;li&gt;The Card component, which is passed the $item and displays the $item information in the card, as well as timestamp of last render&lt;/li&gt;
&lt;li&gt;The Edit component, a modal which when triggered is passed an $item to update, and then emits a change event when $item is saved.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The App
&lt;/h3&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%2Fuploads%2Farticles%2Ft0rk6lz24xz0fqll4r07.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%2Fuploads%2Farticles%2Ft0rk6lz24xz0fqll4r07.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Index component code
&lt;/h3&gt;

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

class Index extends Component
{
    public $tasks;

    public function render()
    {
        $this-&amp;gt;tasks = Task::all();
        return view('livewire.index');
    }
}


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  The Index component blade
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&amp;lt;div class="py-10 w-full flex
    justify-center min-h-screen items-center
    bg-black text-white
    text-sm"
    &amp;lt;div class="w-full"&amp;gt;
        @foreach($tasks as $task)
            &amp;lt;div wire:key="task-{{$loop-&amp;gt;index}}"&amp;gt;
                &amp;lt;livewire:task.card :task="$task"/&amp;gt;
                &amp;lt;button 
       id="complete-{{$loop-&amp;gt;index}}"
       wire:click="$emitTo('task.edit', 'show', {{$task-&amp;gt;id}})"&amp;gt; 
                   Edit
                 &amp;lt;/button&amp;gt;
            &amp;lt;/div&amp;gt;
        @endforeach
    &amp;lt;/div&amp;gt;
    &amp;lt;livewire:task.edit /&amp;gt;
&amp;lt;/div&amp;gt;


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  The Edit component code
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

class Edit extends Component
{
    protected $listeners = ['show'];
    public $task;
    public $showing = false;

    protected $rules = [
        'task.status' =&amp;gt; 'required',
        'task.name' =&amp;gt; 'required|string|max:255'
    ];

    public function show(Task $task){
        $this-&amp;gt;task = $task;
        $this-&amp;gt;showing = true;
    }

    public function render(){
        return view('livewire.task.edit');
    }

    public function save(){
        $this-&amp;gt;validate();
        $this-&amp;gt;task-&amp;gt;save();
        $this-&amp;gt;showing = false;

        //tell card to refresh
        $this-&amp;gt;emit('update-task-' . $this-&amp;gt;task-&amp;gt;id);
    }
}


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  The Edit component blade
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&amp;lt;div class="{{$showing? '' : 'hidden'}}"
    wire:click="$set('showing',false)"&amp;gt;
    @if($task)
     &amp;lt;form wire:click.stop&amp;gt;
        &amp;lt;div&amp;gt;
            Task
            &amp;lt;input type="text" wire:model="task.name"&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div&amp;gt;Status
            &amp;lt;select wire:model="task.status"&amp;gt;
             &amp;lt;option value="Delayed"&amp;gt;Delay&amp;lt;/option&amp;gt;
             &amp;lt;option value="Completed"&amp;gt;Complete&amp;lt;/option&amp;gt;
             &amp;lt;option value="Pending"&amp;gt;Not Started&amp;lt;/option&amp;gt;
             &amp;lt;option value="Canceled"&amp;gt;Cancel&amp;lt;/option&amp;gt;
            &amp;lt;/select&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div class="w-full text-right"&amp;gt;
            &amp;lt;button 
            wire:click.prevent="$set('showing', false)"
            &amp;gt;
            Cancel
        &amp;lt;/button&amp;gt;
        &amp;lt;button wire:click.prevent="save"&amp;gt;
          Save
        &amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
     &amp;lt;/form&amp;gt;
    @endif
&amp;lt;/div&amp;gt;


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  Dynamic Livewire Listeners
&lt;/h3&gt;

&lt;p&gt;There's nothing unusual in the above code, the modal hide/show is pretty standard, and we have the Edit button emit an event that populates the Edit component with a specific task ands unhides the modal.  For brevity I removed the tailwind classes, so this will look a little weird, but it works.  &lt;/p&gt;

&lt;p&gt;Instead of using AlpineJS to show hide I just went with standard blade/livewire.  The part I want to draw attention to in the above code snippets is the last line of the save function in the Edit Component:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$this-&amp;gt;emit('update-task-' . $this-&amp;gt;task-&amp;gt;id);


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

&lt;/div&gt;

&lt;p&gt;Here we are emitting an event that is very specific to just this $task.  Now let's look at the code behind of the Card component:&lt;/p&gt;

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

class Card extends Component
{
    public $listeners = []; // must be public!
    public $task;

    public function mount($task){
      // add listener specific to this task only.
      $this-&amp;gt;listeners =["update-task-" . $task-&amp;gt;id =&amp;gt;"updateTask"];  
    }

    public function updateTask(){
        // calling this triggers render, 
        // no code needed here
    }

    public function render(){
        return view('livewire.task.card');
    }
}


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

&lt;/div&gt;

&lt;p&gt;Here I've added a mount() function that adds a $task-&amp;gt;id specific listener, and points to an empty function.  Now, when a $task is edited and saved, ONLY this Card instance will be listening for that specific event, and only this card will refresh, the rest of the Index page will stay unaltered.&lt;/p&gt;

&lt;p&gt;Source code for this project can be found (using Laravel 9, PHP 8.1, Tailwind 2) &lt;a href="https://github.com/crazedVic/dynamic-listeners-livewire" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>livewire</category>
      <category>events</category>
      <category>listeners</category>
    </item>
    <item>
      <title>Laravel 8 and Fontawesome without SASS</title>
      <dc:creator>Victor R.</dc:creator>
      <pubDate>Wed, 02 Feb 2022 19:52:08 +0000</pubDate>
      <link>https://dev.to/crazedvic/laravel-8-and-fontawesome-without-sass-24p0</link>
      <guid>https://dev.to/crazedvic/laravel-8-and-fontawesome-without-sass-24p0</guid>
      <description>&lt;p&gt;Did a bunch of digging around today, without much luck, as most articles still require you to use scss/sass, are referencing older versions of Laravel.  Plus the official documentation isn't stellar either.  This article should serve as a quick reference to get things running.&lt;/p&gt;

&lt;p&gt;First install these:&lt;br&gt;
&lt;code&gt;npm install @fortawesome/fontawesome-svg-core&lt;/code&gt;&lt;br&gt;
&lt;code&gt;npm install @fortawesome/free-solid-svg-icons&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then edit your &lt;code&gt;resources/js/app.js&lt;/code&gt; and add these lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { library,dom} from '@fortawesome/fontawesome-svg-core';
import { faAirFreshener } from '@fortawesome/free-solid-svg-icons/faAirFreshener';
import { faAddressBook } from '@fortawesome/free-solid-svg-icons/faAddressBook';

library.add(faAddressBook, faAirFreshener)

dom.watch()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure your blade app layout file has the import in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- Scripts --&amp;gt;
&amp;lt;script src="{{ mix('js/app.js') }}" defer&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now open your blade file of choice and add this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;i class="fas fa-address-book"&amp;gt;&amp;lt;/i&amp;gt;
&amp;lt;i class="fas fa-air-freshener"&amp;gt;&amp;lt;/i&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure npm run watch is using mix and is running. That's it.&lt;/p&gt;

&lt;p&gt;Couple of side notes:&lt;br&gt;
I tried using&lt;br&gt;
&lt;code&gt;import { faAirFreshener, faAddressBook } from '@fortawesome/free-solid-svg-icons';&lt;/code&gt;&lt;br&gt;
But my public/js/app.js file blew up to 1.51mb.  Importing them individually kept the js file to 795kb.  I tried a variety of approaches but the above is the only one that didn't make my js file blow up in size.&lt;/p&gt;

&lt;p&gt;My webpack.mix.js was updated for tailwindcss so it's not quite the default out-of-the-box version, here's what it looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const mix = require('laravel-mix');

mix.disableNotifications()

mix.js('resources/js/app.js', 'public/js')
 //   .sourceMaps()
    .postCss('resources/css/app.css', 'public/css', [
        require('postcss-import'),
        require('tailwindcss'),
    ]);

if (mix.inProduction()) {
    mix.version();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>fontawesome</category>
      <category>laravel</category>
      <category>webpack</category>
      <category>svg</category>
    </item>
    <item>
      <title>Stripe, PHP, Subscriptions - Quick Start Guide</title>
      <dc:creator>Victor R.</dc:creator>
      <pubDate>Fri, 09 Oct 2020 16:59:29 +0000</pubDate>
      <link>https://dev.to/crazedvic/stripe-php-subscriptions-quick-start-guide-4mj1</link>
      <guid>https://dev.to/crazedvic/stripe-php-subscriptions-quick-start-guide-4mj1</guid>
      <description>&lt;p&gt;[original: October 7, 2020]&lt;br&gt;
[updated: October 19, 2020]&lt;br&gt;
[updated: October 21, 2020]&lt;/p&gt;

&lt;p&gt;First off, let me say that Stripe is powerful.  They have built a very robust, flexible subscription api that can probably handle anything you throw at it.  However with such flexibility, inevitably comes complexity.  Their documentation is good, and their developer support is awesome, but I would have loved to find a quick guide like this to get me started.&lt;/p&gt;

&lt;p&gt;Second, the development of plugins for newer frameworks such as Flutter, and even more so Flutter web by the Stripe team is severely lagging.  This means we need to build everything in PHP and expose what is needed to the Flutter clients via our REST api.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;UPDATE: So I realized just before launching that we had not taken into account sales tax.  Having used Stripe for straight up purchases in the past, we just managed invoices in our system and had Stripe just process the total amounts rather than handling tax and sub total specifically.  Worked like a charm.  But to my dismay, subscriptions does NOT work this way.  In short, we now need to enter tax rates for EVERY region we wish to sell into.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stripe.com/docs/billing/taxes/tax-rates"&gt;https://stripe.com/docs/billing/taxes/tax-rates&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;So after we MANUALLY add tax-rates for every region/state/country into the stripe dashboard, or write some code to create them all via the api, and then correlate those tax rate id's back to the regions in our own system, we can apply those tax rate id's in an array to the subscription upon creation.  There's no way to apply a tax rate to the subscription directly.  This was our "tap out" moment.  As powerful as Stripe is, just getting a simple monthly subscription service working is just not worth this much effort.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So, here's what we need to achieve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;get list of products and for each product the price tiers to show the customer&lt;/li&gt;
&lt;li&gt;allow customer to add a payment method, in this case, a credit card&lt;/li&gt;
&lt;li&gt;create a stripe customer account for the customer and associate the credit card to it.&lt;/li&gt;
&lt;li&gt;collect the product, the price, the payment method and create a subscription&lt;/li&gt;
&lt;li&gt;let customer cancel a subscription, and in our specific use case, this means they keep the plan until the next renewal date, then it ends.&lt;/li&gt;
&lt;li&gt;let customer change plan they are on for a product&lt;/li&gt;
&lt;li&gt;let customer change the payment method aka they are using on a subscription&lt;/li&gt;
&lt;li&gt;let customer view their current subscriptions&lt;/li&gt;
&lt;li&gt;let customer view all invoices related to a subscription&lt;/li&gt;
&lt;li&gt;track subscriptions in your own db&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's get started!&lt;/p&gt;

&lt;p&gt;Step 1. &lt;br&gt;
Create the products and their prices in Stripe Dashboard. This is pretty straightforward, and not a code thing, so skipping details.&lt;/p&gt;

&lt;p&gt;Step 2.&lt;br&gt;
Get list of products and prices:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$products = \Stripe\Product::all([]);

foreach($products as $product){
  $product-&amp;gt;prices = \Stripe\Price::all(['product'=&amp;gt;$product-&amp;gt;id])-&amp;gt;data;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 3.&lt;br&gt;
Create a customer account.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$customer = \Stripe\Customer::create(([
        'email' =&amp;gt; 'ed@ed.com',
        'description' =&amp;gt; 'Valued Customer',
        'name' =&amp;gt; 'Ed Ward'
]));
$stripe_customer_id = $customer-&amp;gt;id;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 4.&lt;br&gt;
Create Payment Method and then a SetupIntent which will associate the customer with the payment method and validate the card.  I chose confirm true to validate card and usage to off_session because there's a trial period so the first payment will be offline.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$pmt_method = \Stripe\PaymentMethod::create([
     'type'=&amp;gt;'card',
     'card'=&amp;gt; [
         'number' =&amp;gt; '4242424242424242',
         'exp_month' =&amp;gt; 2,
         'exp_year'=&amp;gt; 2022,
         'cvc' =&amp;gt; '343',
         ]
]);

$intent = \Stripe\SetupIntent::create([
      'payment_method_types'=&amp;gt;['card'],
      'payment_method' =&amp;gt; $pmt_method-&amp;gt;id,
      'customer' =&amp;gt; $stripe_customer_id,
      'description' =&amp;gt; 'Associate cc with cust for subscription',
      'confirm' =&amp;gt; true,
      'usage' =&amp;gt; "off_session"
]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 5.&lt;br&gt;
We now have a payment method, a customer, a product and a price.  In stripe you actually subscribe to the price not the product.  Let's do that now.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$stripe_sub = \Stripe\Subscription::create([
       'customer' =&amp;gt; $stripe_customer_id,
       'default_payment_method' =&amp;gt; $pmt_method-&amp;gt;id,
       'items' =&amp;gt; [
            ['price' =&amp;gt; $price_id]
            ]
]);
$subscription_id = $stripe_sub-&amp;gt;id;
$subscription_item_id = $stripe_sub-&amp;gt;items-&amp;gt;data[0]-&amp;gt;id;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 6.&lt;br&gt;
Customers should be able to cancel their subscription.  Originally I tried using Delete subscription but this was instant and not what we wanted.  The following approach lets the current paid period run its course first, and it deletes the payment method from the subscription. &lt;/p&gt;

&lt;p&gt;NOTE: While a subscription is set to cancel at period end, cancel_at is set to period_end, canceled_at is set to current datetime, cancel_at_period_end is set to true (by us), status remains active.  In this state, the cancel_at_period_end can be changed back to false, which restores the subscription.  Once the subscription cancel_at date has past, the status is changed by stripe to 'canceled', the ended_at datetime is set.  Once the subscription is in state 'canceled' it cannot be changed, and if user wishes to restart subscription you must create a new subscription.&lt;/p&gt;

&lt;p&gt;It does not delete the subscription, allowing user to renew at a later time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;\Stripe\Subscription::update($subscription_id,
      ["cancel_at_period_end" =&amp;gt; true, 
      "default_payment_method" =&amp;gt; ""
]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 7.&lt;br&gt;
Changing the plan, in other words, same product but different price id.  This will also be an update.  It's helpful here if you store the subscription_item id somewhere in your own db, as this essentially replaces the price_id on an item.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;\Stripe\Subscription::update($subscription_id,
      [
       'items' =&amp;gt; [
        [   'id' =&amp;gt; $subscription_item_id,
            'price' =&amp;gt; $data-&amp;gt;price_id
        ]
      ]
]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 8.&lt;br&gt;
Changing the payment method for a subscription with status 'active'.  Basically repeat Step 4, and then update the subscription as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;\Stripe\Subscription::update($subscription_id,
       [
        'default_payment_method' =&amp;gt; $new_payment_method_id
]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 9.&lt;br&gt;
Customers should be able to review their current subscriptions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;\Stripe\Subscription::all([
            'customer'=&amp;gt; $stripe_customer_id
        ]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 10.&lt;br&gt;
Customers should be able to view all invoices paid relating to a subscription.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$invoices = \Stripe\Invoice::all(['subscription'=&amp;gt; $subscription_id])-&amp;gt;data;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 11.&lt;br&gt;
Once I finally had this working, my subscriptions table had changed quite a few times to handle information I didn't know i'd need, or want to store for brevity, like subscription item id and nickname.  Once the dust settled this is what the table looked like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE TABLE `subscription` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `customer_id` varchar(45) NOT NULL,
  `subscription_id` varchar(45) NOT NULL,
  `price_id` varchar(45) NOT NULL,
  `item_id` varchar(45) NOT NULL,
  `product_id` varchar(45) NOT NULL,
  `default_payment_method` varchar(45) DEFAULT NULL,
  `nickname` varchar(245) DEFAULT NULL,
  `description` varchar(245) DEFAULT NULL,
  `active` tinyint(1) DEFAULT NULL,
  `amount` int(11) DEFAULT NULL,
  `currency` varchar(5) DEFAULT NULL,
  `frequency` varchar(45) DEFAULT NULL,
  `period_start` datetime DEFAULT NULL,
  `period_end` datetime DEFAULT NULL,
  `canceled_at` datetime DEFAULT NULL,
  `meta_stripe` json DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hope this helps even just one person out there!&lt;/p&gt;

</description>
      <category>php</category>
      <category>stripe</category>
      <category>subscription</category>
      <category>api</category>
    </item>
    <item>
      <title>Improving redirects in PHP Built-in Webserver</title>
      <dc:creator>Victor R.</dc:creator>
      <pubDate>Mon, 28 Sep 2020 20:35:32 +0000</pubDate>
      <link>https://dev.to/crazedvic/improving-redirects-in-php-built-in-webserver-489d</link>
      <guid>https://dev.to/crazedvic/improving-redirects-in-php-built-in-webserver-489d</guid>
      <description>&lt;p&gt;This issue arose when I tried using a period in my parameters within my REST API.  One could question the point of this, but let's assume there's a good solid business reason for it.&lt;/p&gt;

&lt;p&gt;This is the sample url:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;http://localhost:8009/url.target/www.google.com&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This url works absolutely fine on nginx and apache.  However the built in php server, when it sees a dot / decimal / period in the url, it tries to find the file.  So attempting to access this url on the PHP built-in web server results in:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;url.target/www.google.com was not found on this server&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The way to change the default behaviour of the built-in server is to add a custom router script.  I found this online in a stack overflow post...  after much, much searching:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

if (file_exists($_SERVER['DOCUMENT_ROOT'] . $path)) {
    return false;
} else {
    $_SERVER['SCRIPT_NAME'] = 'index.php';
    include './public/index.php';
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I am running the API from a ./public folder, index.php, as you can see in the above code.  This script checks if an actual file exists at the requested url, and if not redirects by default to the public/index.php, which is what we want.&lt;/p&gt;

&lt;p&gt;Adding in a router however changed how php handles paths, so this code:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;require '../flight/Flight.php';&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;No longer worked with the router.php in play.  I had to change it to the following:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;require __DIR__ . '/../flight/Flight.php';&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now to run the built in web server, keeping in mind that the router.php file is in the project root, and I run this from the root:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;php -S 0.0.0.0:8009 -t public router.php&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;(i prefer 0.0.0.0 so i can access the site from my phone on same LAN)&lt;/p&gt;

&lt;p&gt;Hope this helps others out there that may run into the same issue.&lt;/p&gt;

</description>
      <category>php</category>
      <category>dot</category>
      <category>webserver</category>
      <category>redirect</category>
    </item>
    <item>
      <title>Query &amp; Update Firestore Documents in Angular 7</title>
      <dc:creator>Victor R.</dc:creator>
      <pubDate>Fri, 15 Feb 2019 04:22:25 +0000</pubDate>
      <link>https://dev.to/crazedvic/query--update-firestore-documents-in-angular-7-5fhg</link>
      <guid>https://dev.to/crazedvic/query--update-firestore-documents-in-angular-7-5fhg</guid>
      <description>&lt;p&gt;February 14th, 2019 &lt;/p&gt;

&lt;p&gt;As I continue to build the time tracking system I run into challenges. Challenges so annoying that I inevitably always end up having to scour stackoverflow for hours  on end.  Searching desperately for relevant knowledge and eventually a viable solution.  And now I am here to share those latest findings.&lt;/p&gt;

&lt;p&gt;So I have a week navigation control.  Users can move forward or backward through the weeks of the year.  I key timesheets on year_week, and user_id.  As the user clicks forward or back, it should load the right timesheet, if it exists and populate the form (as discussed in my previous post).  Then if the user makes updates to the timesheet, it should update the document in Firestore.  Simple enough.&lt;/p&gt;

&lt;p&gt;So the key requirements here are: access document via a query, NOT id, show that document's data, have a reference to the underlying document, so I can update it, be fast, and minimize trips to the server, in the interest of my wallet.&lt;/p&gt;

&lt;p&gt;Here's my Client interface, for reference:&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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Client&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&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;Here's the variables I'm going to need for this, declared in AppComponent.ts:&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="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;clientRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DocumentReference&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;clients&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;any&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="nl"&gt;myClient&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quick explanation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;clientRef = will hold a DocumentReference to the selected Client&lt;/li&gt;
&lt;li&gt;clients = will hold a list of all Clients to select from&lt;/li&gt;
&lt;li&gt;myClient = will be the currently selected Client&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's the html form, AppComponent.html:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;*ngFor=&lt;/span&gt;&lt;span class="s"&gt;"let client of clients | async"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt; &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"selectClient(client)"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{client.name}}&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Selected Client: {{myClient?.name}}&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"updateSelectedClient()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Update Client&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So basically load up all the clients, click client name to select it. It will show up as the selected client, then click Update Client to see the Client update in both the list, and in the Firestore console, in real time.&lt;/p&gt;

&lt;p&gt;When a user clicks a client name, I am actually going to perform a query by client name, as I don't have ID's.  This is intentional because of my actual use case, as outlined in the introduction.  Here's what happens:&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;async&lt;/span&gt; &lt;span class="nx"&gt;selectClient&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;Client&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;snapshotResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&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;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;clients&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&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;==&lt;/span&gt;&lt;span class="dl"&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;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
           &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
           &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;snapshotChanges&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
           &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;flatMap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clients&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;clients&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; 

        &lt;span class="nx"&gt;snapshotResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doc&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;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;myClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Client&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;doc&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clientRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ref&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;You'll notice I pipe the results into flatMap, this flattens the result array which only has 1 result anyway, making the remaining code cleaner.  I wait for the snapshotResult to come back, then I grab and assign my DocumentReference to clientRef and populate myClient with the document data.&lt;/p&gt;

&lt;p&gt;Finally to test if this will allow me to update, I created the following 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="nx"&gt;updateSelectedClient&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&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;myClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&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;myClient&lt;/span&gt;&lt;span class="p"&gt;.&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="s1"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&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;clientRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&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;myClient&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;I am just appending a period to the end of the client name, to make sure this is working.  Clicking the UpdateClient button I could see the Selected Client label, the Firestore document and the name in the list update in real time. &lt;/p&gt;

&lt;p&gt;ADDENDUM&lt;/p&gt;

&lt;p&gt;You can achieve the same result by using BehaviorSubject, so clicking on a client merely changes the value of the subject, which in turn will trigger the query.  As my current year-week is already a subject, I figured I'd quickly add this.&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="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;_currentClient&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;BehaviorSubject&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then initialize it in the constructor&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;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_currentClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;BehaviorSubject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add an ngOnInit and subscribe to the subject&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="nx"&gt;ngOnInit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&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;_currentClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&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;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;snapshotResult&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;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;clients&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
                &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&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;==&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;snapshotChanges&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;flatMap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clients&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;clients&lt;/span&gt;&lt;span class="p"&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;snapshotResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doc&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;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;myClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Client&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;doc&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clientRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And change selectClient() function to just this:&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;async&lt;/span&gt; &lt;span class="nx"&gt;selectClient&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;Client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&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;_currentClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&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;name&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 functionality overall remains the same, just using SubjectBehavior instead.&lt;/p&gt;

</description>
      <category>flatmap</category>
      <category>snapshotchanges</category>
      <category>firestore</category>
      <category>angular</category>
    </item>
    <item>
      <title>Using PatchValue on FormArrays in Angular 7</title>
      <dc:creator>Victor R.</dc:creator>
      <pubDate>Thu, 14 Feb 2019 16:43:12 +0000</pubDate>
      <link>https://dev.to/crazedvic/using-patchvalue-on-formarrays-in-angular-7-2c8c</link>
      <guid>https://dev.to/crazedvic/using-patchvalue-on-formarrays-in-angular-7-2c8c</guid>
      <description>&lt;p&gt;February 14th, 2019&lt;/p&gt;

&lt;p&gt;So I created fancy form with nested FormArrays, and was able to very easily persist that data as a document in Firestore.  Specifically I was working on a weekly timesheet view, and being able to see it save exactly as it was in the angular form was quite awesome.  Then it came time to reload that data into the same form. And that's when the pain began...&lt;/p&gt;

&lt;p&gt;I have actually found Angular's reactive forms pretty terrible - they are easy to get up and running with little to no effort, but then to actually use them in production code suddenly demands a fairly steep learning curve.  In Angular 7 it is said that two way binding with ngModel is no longer possible, so this only adds to the confusion.  But enough ranting, let's get started.&lt;/p&gt;

&lt;p&gt;The structure of the form and the data is as follows&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Team 
  Lines
    Line
      Players
        Player
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So a team can have many lines and each line can have many players.  Keeping it simple.  There's no limit or minimums to the number of lines or players.&lt;/p&gt;

&lt;p&gt;The challenge we face is that when the form first renders, it does not know how many lines or how many players it will need to render out form elements for.  We need to look at the data, parse through the data and build our form so that it has all the elements we need.  Then if we've done things correctly, we can just patchValue the form formgroup and all the values should appear.&lt;/p&gt;

&lt;p&gt;First let's look at some sample seed data:&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;seedData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;team_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The Team&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lines&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;line 1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;players&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;first_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1a&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;last_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;first_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2a&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;last_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;first_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;3a&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;last_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&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="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;line 2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;players&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;first_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1b&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;last_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;first_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2b&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;last_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;first_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;3b&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;last_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&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="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;line 3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;players&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;first_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1c&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;last_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;first_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2c&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;last_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;first_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;3c&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;last_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&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="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;And in ngOnInit I first set the form up as follows:&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="nx"&gt;ngOnInit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&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;dataModel&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;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// created a simple form with no populated formarray&lt;/span&gt;
    &lt;span class="c1"&gt;// this will be handled by the data load instead&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;cvForm&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;_fb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;group&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
       &lt;span class="na"&gt;team_name&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="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Validators&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="p"&gt;]],&lt;/span&gt;
       &lt;span class="na"&gt;lines&lt;/span&gt;&lt;span class="p"&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;_fb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;array&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="c1"&gt;//subscribe to value changes on form&lt;/span&gt;
     &lt;span class="c1"&gt;// only way i've found i can manipulate the form data&lt;/span&gt;
     &lt;span class="c1"&gt;// through code and have it update the underlying dataModel&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;cvForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valueChanges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&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;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataModel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&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;Let's look at the code:&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="nx"&gt;loadForm&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="c1"&gt;// create lines array first&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;line&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&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;lines&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="o"&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;linesFormArray&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;cvForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lines&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;FormArray&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
       &lt;span class="nx"&gt;linesFormArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&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;line&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

       &lt;span class="c1"&gt;//for each line, now add all the necessary player formgroups&lt;/span&gt;
       &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;player&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;player&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&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;lines&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;players&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;player&lt;/span&gt;&lt;span class="o"&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;playersFormsArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;linesFormArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;at&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;players&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;FormArray&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="nx"&gt;playersFormsArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&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;player&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="c1"&gt;// once we setup the form with all the arrays and such, we can just&lt;/span&gt;
    &lt;span class="c1"&gt;// patch the form:&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;cvForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;patchValue&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see I examine the data, loop through the child arrays in the data, and build out my form.  It will create all the form elements it needs, here's the get functions it's calling and pushing into the formArrays:&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;get&lt;/span&gt; &lt;span class="nx"&gt;player&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="nx"&gt;FormGroup&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&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;_fb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;group&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;first_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;last_name&lt;/span&gt;&lt;span class="p"&gt;:&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="kd"&gt;get&lt;/span&gt; &lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="nx"&gt;FormGroup&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&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;_fb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;group&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;players&lt;/span&gt;&lt;span class="p"&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;_fb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
         &lt;span class="p"&gt;]),&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, on save the last trick is to reset the form, in other words, clear all the controls and start fresh, so that subsequent loads don't keep adding on top of the existing formArrays.  From what I've read, actually using removeAt of all the formArrays and their children would break my subscription.  So the trick is to do as follows:&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="nx"&gt;saveForm&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="c1"&gt;//save form values to storeData and reset the form&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;storeData&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;cvForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getRawValue&lt;/span&gt;&lt;span class="p"&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;cvForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// IMPORTANT: reset will not remove form elements only clear them&lt;/span&gt;
    &lt;span class="c1"&gt;// So we need to clear the FormArrays as well &lt;/span&gt;
    &lt;span class="c1"&gt;// without losing our subscription! &lt;/span&gt;
    &lt;span class="c1"&gt;// this seems to work fine:&lt;/span&gt;
     &lt;span class="p"&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;cvForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lines&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;FormArray&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;controls&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;splice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&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;I am hoping this will help someone else get to where i am today just a little faster.  You can find the working code here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackblitz.com/edit/angular-patch-value-deeply-nested-component-utk3qv"&gt;https://stackblitz.com/edit/angular-patch-value-deeply-nested-component-utk3qv&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>binding</category>
      <category>formgroup</category>
      <category>reactiveform</category>
    </item>
    <item>
      <title>Nested FormArrays in Angular ReactiveForms </title>
      <dc:creator>Victor R.</dc:creator>
      <pubDate>Thu, 07 Feb 2019 23:26:27 +0000</pubDate>
      <link>https://dev.to/crazedvic/nested-formarrays-in-angular-reactiveforms--4hm</link>
      <guid>https://dev.to/crazedvic/nested-formarrays-in-angular-reactiveforms--4hm</guid>
      <description>

&lt;p&gt;Feb 7, 2019&lt;/p&gt;

&lt;h1&gt;
  
  
  Angular Reactive Forms with lots of Nesting
&lt;/h1&gt;

&lt;p&gt;I looked everywhere for a solution I could just copy and paste into my project but with no luck, so here's my attempt at providing it for the next poor soul stuck in my situation. I've tried to keep the code as simple as possible.&lt;/p&gt;

&lt;h1&gt;
  
  
  You have a league
&lt;/h1&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;league_details: this.fb.group({
        name: "",
        founder: ""
      })
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  A league has teams
&lt;/h1&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;this.leagueForm = this.fb.group({
      league_details: this.fb.group({
        name: "",
        founder: ""
      }),
      teams: this.fb.array([this.teams])
    });
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Teams have names and players
&lt;/h1&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get teams(): FormGroup {
    return this.fb.group({
      team_name: "",
      players: this.fb.array([this.players])
    });
  }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Players have names and numbers
&lt;/h1&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get players(): FormGroup {
    return this.fb.group({
      player_name: "",
      player_number: ""
    });
  }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  You have a FormGroup
&lt;/h1&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;form [formGroup]="leagueForm"&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Show League Detail
&lt;/h1&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="form-header" formGroupName="league_details"&amp;gt;
    &amp;lt;label&amp;gt;League Name &amp;lt;input formControlName="name"/&amp;gt;&amp;lt;/label&amp;gt;
    &amp;lt;label&amp;gt;Founder &amp;lt;input formControlName="founder"/&amp;gt;&amp;lt;/label&amp;gt;
  &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Show Teams
&lt;/h1&gt;

&lt;p&gt;It's VITAL you have a wrapping div that defines formArrayName!&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div formArrayName="teams"&amp;gt;
    &amp;lt;div class="teams" *ngFor="let team of leagueForm.get('teams').controls;
             let teamIndex = index" [formGroupName]="teamIndex"&amp;gt;
      &amp;lt;label&amp;gt;Team Name &amp;lt;input formControlName="team_name"/&amp;gt;&amp;lt;/label&amp;gt;
      &amp;lt;!--  div with formArrayName='players' goes here (see below) --&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Show Players inside Teams
&lt;/h1&gt;

&lt;p&gt;Again, important you have a wrapping div with formArrayName. Also, you need to add players in context of the team. Notice in ngFor i am referencing the team variable&lt;br&gt;
defined in the ngFor loop above for teams. I will also need to reference this team when removing or adding players.&lt;/p&gt;

&lt;p&gt;Also notice the &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; element, this is how you reference the field for validation functionality.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div formArrayName="players"&amp;gt;
    &amp;lt;div class="players" *ngFor="let player of team.get('players').controls;
        let playerIndex=index" [formGroupName]="playerIndex"&amp;gt;
        &amp;lt;label&amp;gt;Player Name &amp;lt;input formControlName="player_name" /&amp;gt;
        &amp;lt;label&amp;gt;Player Number &amp;lt;input formControlName="player_number"/&amp;gt;&amp;lt;/label&amp;gt;
        &amp;lt;span *ngIf="player.get('player_number').touched"&amp;gt;touched!&amp;lt;/span&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Adding Teams
&lt;/h1&gt;

&lt;p&gt;Place ADD button just above the div that defines the formArrayArrayName teams&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; &amp;lt;button type="button" (click)="addTeam()"&amp;gt;Add Team&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;addTeam() {
    (this.leagueForm.get("teams") as FormArray).push(this.teams);
  }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Adding Players
&lt;/h1&gt;

&lt;p&gt;Place ADD button just above the div that defines the formArrayName players, and remember to pass in the team variable from the enclosing ngFor loop.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;button type="button" (click)="addPlayer(team)"&amp;gt;Add Player&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;addPlayer(team) {
    team.get("players").push(this.players);
  }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;See project here on github:&lt;br&gt;
&lt;a href="https://github.com/crazedVic/angularnestedformarrays"&gt;https://github.com/crazedVic/angularnestedformarrays&lt;/a&gt;&lt;/p&gt;


</description>
      <category>angular</category>
      <category>formarray</category>
      <category>nesting</category>
      <category>reactiveforms</category>
    </item>
    <item>
      <title>Checkbox Group Component in React-Final-Form</title>
      <dc:creator>Victor R.</dc:creator>
      <pubDate>Tue, 06 Nov 2018 20:39:11 +0000</pubDate>
      <link>https://dev.to/crazedvic/checkbox-group-component-in-react-final-form-5431</link>
      <guid>https://dev.to/crazedvic/checkbox-group-component-in-react-final-form-5431</guid>
      <description>

&lt;p&gt;&lt;em&gt;Posted November 6, 2018&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Going to keep this short, because, by the time you most likely find this post, all you want is to just see it work, then copy and paste and get back to coding...&lt;/p&gt;

&lt;p&gt;First imports these were required at minimum, though you will also need the 'final-form' package.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import { Form, Field } from "react-final-form";
import { FieldArray } from 'react-final-form-arrays'
import arrayMutators from 'final-form-arrays'
import Checkbox from "@material-ui/core/Checkbox";
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Setup your array of options:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const myOptions = ["Meat Lover", "Veggie Heaven", "Hawaii-5-0", "Inferno"];
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Setup your onSubmit method:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const onSubmit = async values =&amp;gt; {
  window.alert(JSON.stringify(values, 0, 2));
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is your custom component using standard input of type checkbox:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const CheckboxGroup = ({ fields, options }) =&amp;gt; {
  const toggle = (event, option) =&amp;gt; {
    if (event.target.checked) fields.push(option);
    else fields.remove(option);
  };
  return (
    &amp;lt;div style={{ color: "blue" }}&amp;gt;
      {options.map(option =&amp;gt; (
        &amp;lt;div key={option}&amp;gt;
          &amp;lt;input
            type="checkbox"
            onClick={event =&amp;gt; toggle(event, option)}
          /&amp;gt;
          {option}
        &amp;lt;/div&amp;gt;
      ))}
    &amp;lt;/div&amp;gt;
  );
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is a more fancy custom component using Material-UI Checkbox:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const CheckboxGroupMUI = ({ fields, options }) =&amp;gt; {

  const toggle = (event, option) =&amp;gt; {
    if (event.target.checked) fields.push(option);
    else fields.remove(option);
  };

  return (
    &amp;lt;div style={{ color: "darkblue" }}&amp;gt;
      {options.map(option =&amp;gt; (
        &amp;lt;div key={option}&amp;gt;
          &amp;lt;Checkbox
            value={option}
            onChange={event =&amp;gt; toggle(event, option)}
          /&amp;gt;
          {option}         
        &amp;lt;/div&amp;gt;
      ))}
    &amp;lt;/div&amp;gt;
  );
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Ok now here's the main part:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function App() {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h3&amp;gt;Checkboxes FML&amp;lt;/h3&amp;gt;     
      &amp;lt;Form
        onSubmit={onSubmit}
        mutators={{
          ...arrayMutators
        }}
        render={({ handleSubmit, form, submitting, pristine, values }) =&amp;gt; (
          &amp;lt;form onSubmit={handleSubmit}&amp;gt;

            &amp;lt;label&amp;gt;Pizza using Custom Checkbox Group&amp;lt;/label&amp;gt;
            &amp;lt;FieldArray
              name="pizzas-1"
              component={CheckboxGroup}
              options={myOptions}
            /&amp;gt;
            &amp;lt;hr /&amp;gt;
            &amp;lt;label&amp;gt;Pizza using Custom Material-UI Checkbox Group&amp;lt;/label&amp;gt;
            &amp;lt;FieldArray
              name="pizzas-2"
              component={CheckboxGroupMUI}
              options={myOptions}
            /&amp;gt;
            &amp;lt;hr /&amp;gt;
            &amp;lt;div&amp;gt;
              &amp;lt;button type="submit" disabled={submitting || pristine}&amp;gt;
                Submit
              &amp;lt;/button&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;pre&amp;gt;{JSON.stringify(values, 0, 2)}&amp;lt;/pre&amp;gt;
          &amp;lt;/form&amp;gt;
        )}
      /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(&amp;lt;App /&amp;gt;, rootElement);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And here it is in action:&lt;br&gt;
&lt;iframe src="https://codesandbox.io/embed/5w511k5v0k"&gt;&lt;/iframe&gt;&lt;/p&gt;

&lt;p&gt;Hope this helps.  If you have questions, please post below.&lt;/p&gt;


</description>
      <category>fieldarray</category>
      <category>checkbox</category>
      <category>reactfinalform</category>
      <category>stateless</category>
    </item>
  </channel>
</rss>
