title: How to register a dynamically added custom component as a form control within a formgroup
body: <p>I have created some custom components, each of which implements <a href="http://blog.thoughtram.io/angular/2016/07/27/custom-form-controls-in-angular-2.html" rel="nofollow noreferrer"><code>ControlValueAccessor</code></a>, in order that they may function as controls within a <code>FormGroup</code>. Usually, the only thing left to do would be to add the <code>formControlName</code> directive to each custom component in HTML.</p>
  
  <p>However, I'm appending these components to the form at runtime using <a href="https://stackoverflow.com/a/39773331/1087131">this</a> technique. </p>
  
  <p>My problem is that I cannot register these components with a containing <code>FormGroup</code> because I cannot declare the <code>formControlName</code> directive (or any directive, for that matter) with a dynamically added control.</p>
  
  <p><strong>Has anyone else discovered how this might be possible?</strong> At the moment, I'm wrapping each control inside another component so that I can use the <code>formControlName</code> directive but this is just too ugly and labor intensive.</p>
  
  <hr>
  
  <p><strong>Below is a stripped down example of what I've already implemented  as a standalone Angular2 app</strong>, which shows a component (<code>CustomComponent</code>) being programatically added on startup. In order to bind <code>CustomComponent</code> to the <code>FormGroup</code>, I've had to create <code>CustomContainerComponent</code> which I'd prefer to avoid.</p>
  
  <pre><code>import {
    Component, ReflectiveInjector, ViewContainerRef, Compiler, NgModule, ModuleWithComponentFactories,
    OnInit, ViewChild, forwardRef
  } from '@angular/core';
  import {BrowserModule} from '@angular/platform-browser';
  import {NG_VALUE_ACCESSOR, ControlValueAccessor, FormGroup, FormBuilder, ReactiveFormsModule} from '@angular/forms';
  
  
  export class AbstractValueAccessor&lt;T&gt; implements ControlValueAccessor {
    _value: T;
    get value(): T {
      return this._value;
    };
  
    set value(v: T) {
      if (v !== this._value) {
        this._value = v;
        this.onChange(v);
      }
    }
  
    writeValue(value: T) {
      this._value = value;
      this.onChange(value);
    }
  
    onChange = (_) =&gt; {};
    onTouched = () =&gt; {};
  
    registerOnChange(fn: (_: any) =&gt; void): void {
      this.onChange = fn;
    }
  
    registerOnTouched(fn: () =&gt; void): void {
      this.onTouched = fn;
    }
  
  }
  
  export function MakeProvider(type: any) {
    return {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() =&gt; type),
      multi: true
    };
  }
  
  @Component({
    selector: 'app-custom',
    template: `&lt;input type="text" [value]="value"&gt;`,
    providers: [MakeProvider(CustomComponent)]
  })
  class CustomComponent extends AbstractValueAccessor&lt;string&gt; {
  
  }
  
  @Component({
    selector: 'app-custom-container',
    template: `&lt;div [formGroup]="formGroup"&gt;&lt;app-custom formControlName="comp"&gt;&lt;/app-custom&gt;&lt;/div&gt;`
  })
  class CustomContainerComponent {
    formGroup: FormGroup;
  }
  
  @NgModule({
    imports: [BrowserModule, ReactiveFormsModule],
    declarations: [CustomComponent, CustomContainerComponent]
  })
  class DynamicModule {
  }
  
  @Component({
    selector: 'app-root',
    template: `&lt;h4&gt;Dynamic Components&lt;/h4&gt;&lt;br&gt;
               &lt;form [formGroup]="formGroup"&gt;
                 &lt;div #dynamicContentPlaceholder&gt;&lt;/div&gt;
               &lt;/form&gt;`
  })
  export class AppComponent implements OnInit {
  
    @ViewChild('dynamicContentPlaceholder', {read: ViewContainerRef})
    public readonly vcRef: ViewContainerRef;
  
    factory: ModuleWithComponentFactories&lt;DynamicModule&gt;;
    formGroup: FormGroup;
  
    constructor(private compiler: Compiler, private formBuilder: FormBuilder) {
    }
  
    ngOnInit() {
      this.compiler.compileModuleAndAllComponentsAsync(DynamicModule)
        .then((moduleWithComponentFactories: ModuleWithComponentFactories&lt;DynamicModule&gt;) =&gt; {
          this.factory = moduleWithComponentFactories;
          const compFactory = this.factory.componentFactories.find(x =&gt; x.selector === 'app-custom-container');
          const injector = ReflectiveInjector.fromResolvedProviders([], this.vcRef.parentInjector);
          let cmp = this.vcRef.createComponent(compFactory, this.vcRef.length, injector, []);
          (&lt;CustomContainerComponent&gt;cmp.instance).formGroup = this.formGroup;
        });
  
      this.formGroup = this.formBuilder.group({
        'comp': ['hello world']
      })
    }
  }
  
  @NgModule({
    imports: [BrowserModule, ReactiveFormsModule],
    declarations: [AppComponent],
    bootstrap: [AppComponent]
  })
  export class AppModule {
  }
  </code></pre>