title: Component constructor is getting called twice with Angular elements
body: <p>I am working on a recursive query builder form, which is something similar to <a href="https://querybuilder.js.org/" rel="nofollow noreferrer">this</a>, in <strong>angular 7, with reactive form</strong>. Means, the user can keep adding a parallel rule by clicking on <code>Add rule</code> and can add a group by clicking on <code>Add group</code>.
  I have created two components, <code>QueryDesignerComponent</code> and <code>QueryComponent</code>.  <code>QueryDesignerComponent</code> holds the outer container, with <code>AND</code> and <code>OR</code> condition and <code>QueryComponent</code> holds the row input, that's <code>LHS</code>, <code>operator</code> and <code>RHS</code>. </p>
  
  <ol>
  <li>When user clicks <code>Add rule</code> I am growing the rule just by pushing one more entry with <code>QueryComponent</code> inside <code>QueryDesignerComponent</code>. I am repeating this with <code>*ngFor</code>.</li>
  <li>When the user clicks <code>Add group</code> I am callings the <code>QueryDesignerComponent</code> inside <code>QueryComponent</code>, which makes it recursive. I am repeating this with <code>*ngFor</code>.</li>
  </ol>
  
  <p>I am done with the implementation and its working fine within angular app, which has an angular environment. </p>
  
  <p>Now, I am trying to port this flow in <a href="https://angular.io/guide/elements" rel="nofollow noreferrer">angular elements</a>, to make it reusable, regardless of the environment. </p>
  
  <p>this is how I am placing first row [ <code>QueryComponent</code> ] inside <code>QueryDesignerComponent</code>,</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;div class="qd--criteria"&gt;
      &lt;div class="row qd--body qd--clear-margin-lr"&gt;
          &lt;div class="col-md-12 qd--condition-container"&gt;
              &lt;query [data]="data" [operators]="operators" [(queryForm)]="queryForm"&gt;&lt;/query&gt;
          &lt;/div&gt;
      &lt;/div&gt;
  &lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>and this way I am managing the parallel query and groups inside <code>QueryComponent</code>,</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;!--Top level container for query view | everything related should go here: start--&gt;
  &lt;div class="qd--query-container" [formGroup]="queryForm" *ngIf="queryForm"&gt;
      &lt;div class="row" formArrayName="queries"&gt;
          &lt;!--Repeat the dynamically added/removed queries: start--&gt;
          &lt;div class="col-md-12 qd--query-inputs-container" *ngFor="let query of currentQueries.controls; let queryIndex = index"&gt;
              &lt;div class="row qd--query-inputs" [formGroupName]="queryIndex"&gt;
                  &lt;!--Actual query inputs: start--&gt;
                  &lt;div class="col-md-10 qd--condition-holder"&gt;
                      &lt;div class="row no-gutter"&gt;
                          &lt;!--Left hand side input: start--&gt;
  
                          &lt;!--Left hand side input: end--&gt;
  
                          &lt;!--Operator: start--&gt;
  
                          &lt;!--Operator: end--&gt;
  
                          &lt;!--Right hand side input: start--&gt;
  
                          &lt;!--Right hand side input: end--&gt;
                      &lt;/div&gt;
                  &lt;/div&gt;
                  &lt;!--Actual query inputs: start--&gt;
  
                  &lt;!--Group options: start--&gt;
  
                  &lt;!--Group options: end--&gt;
  
                  &lt;!--Group query: start--&gt;
                  &lt;div *ngIf="query !== undefined" class="ai--query-groups"&gt;
                      &lt;div *ngFor="let group of getGroups(query).controls; let groupIndex=index" class="ai--query-group"&gt;
                          &lt;query-designer
                                  [data]="data"
                                  [operators]="operators"
                                  [queryForm]="group"
                                  (removeQueryGroup)="removeQueryGroupHandler($event)"
                                  [queryIndex]="queryIndex"
                                  [groupIndex]="groupIndex"&gt;&lt;/query-designer&gt;
                      &lt;/div&gt;
                  &lt;/div&gt;
                  &lt;!--Group query: end--&gt;
  
              &lt;/div&gt;
          &lt;/div&gt;
          &lt;!--Repeat the dynamically added/removed queries: end--&gt;
      &lt;/div&gt;
  &lt;/div&gt;
  &lt;!--Top level container for query view: start--&gt;
  
  
  &lt;!--Repeat the dynamically added/removed queries: start--&gt;
  &lt;div class="col-md-12 qd--query-inputs-container" *ngFor="let query of currentQueries.controls; let queryIndex = index"&gt;
      &lt;div class="row qd--query-inputs" [formGroupName]="queryIndex"&gt;
          &lt;!--Actual query inputs: start--&gt;
          &lt;div class="col-md-10 qd--condition-holder"&gt;
              &lt;div class="row no-gutter"&gt;
                  &lt;!--Left hand side input: start--&gt;
  
                  &lt;!--Left hand side input: end--&gt;
  
                  &lt;!--Operator: start--&gt;
  
                  &lt;!--Operator: end--&gt;
  
                  &lt;!--Right hand side input: start--&gt;
  
                  &lt;!--Right hand side input: end--&gt;
              &lt;/div&gt;
          &lt;/div&gt;
          &lt;!--Actual query inputs: start--&gt;
  
          &lt;!--Group options: start--&gt;
  
          &lt;!--Group options: end--&gt;
  
          &lt;!--Group query: start--&gt;
          &lt;div *ngIf="query !== undefined" class="ai--query-groups"&gt;
              &lt;div *ngFor="let group of getGroups(query).controls; let groupIndex=index" class="ai--query-group"&gt;
                  &lt;query-designer
                          [data]="data"
                          [operators]="operators"
                          [queryForm]="group"
                          (removeQueryGroup)="removeQueryGroupHandler($event)"
                          [queryIndex]="queryIndex"
                          [groupIndex]="groupIndex"&gt;&lt;/query-designer&gt;
              &lt;/div&gt;
          &lt;/div&gt;
          &lt;!--Group query: end--&gt;
  
      &lt;/div&gt;
  &lt;/div&gt;
  &lt;!--Repeat the dynamically added/removed queries: end--&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>This is how I am creating a custom angular element,</p>
  
  <pre><code>@NgModule({
    imports: [
      CommonModule,
      BrowserModule,
      NgSelectModule,
      FormsModule,
      ReactiveFormsModule,
      CoreModule
    ],
    declarations: [
      AppComponent,
      QueryComponent,
      QueryDesignerComponent
    ],
    entryComponents: [QueryDesignerComponent],
    providers: []
  })
  export class AppModule {
    constructor(private injector: Injector) {
      const strategyFactory = new ElementZoneStrategyFactory(QueryDesignerComponent, injector);
      const customElement = createCustomElement(QueryDesignerComponent, { injector, strategyFactory });
      customElements.define('query-designer', customElement);
    }
  
    ngDoBootstrap() { }
  }
  </code></pre>
  
  <p>In the first render, it's working fine and I am able to add <code>n</code> number of parallel rows. But, when I click the <code>Add group</code>, <code>QueryDesignerComponent</code>'s constructor is getting called twice! This makes the first instance of <code>QueryDesignerComponent</code> to receive <code>undefined</code> and second instance to receive correct values.</p>
  
  <p>I followed <a href="https://stackoverflow.com/questions/38787795/why-ngoninit-called-twice">why ngOnInit called twice?</a>, related <a href="https://github.com/angular/angular/issues/6782" rel="nofollow noreferrer">github issue</a> and  <a href="https://stackoverflow.com/questions/45039946/ngoninit-and-constructor-are-called-twice">ngOnInit and Constructor are called twice</a> but, I found no luck!!</p>
  
  <p>Does anyone know how can I get rid of this issue? Any help/guidance would be much appreciated!</p>