title: Angular Material Stepper - how to dynamically create components to load into steps
body: <p>I have seen a number of similar posts. I wish to be able to use <code>@ngFor</code> to create components to then load into steps of the <a href="https://material.angular.io/components/stepper/overview" rel="nofollow noreferrer">Material Stepper</a></p>
  <p>I have been following an <a href="https://stackblitz.com/edit/angular-1o5zma?file=src/app/hero-job-ad.component.ts" rel="nofollow noreferrer">example of dynamic loading</a>, and some other posts (which are incomplete), and come up with the following.</p>
  <p>First I have a number of components I want to load into the steps. They are just empty apart from the string (eg &quot;component is working&quot;</p>
  <p>eg</p>
  <pre><code>export class StepPage1Component implements OnInit, StepPage {
        constructor() { }
        ngOnInit() {
        }
  }
  </code></pre>
  <p>So I have 3 of these.</p>
  <p>The &quot;root&quot; component is as follows.</p>
  <pre><code>export class WizardStepperComponent implements OnInit {
    @ViewChild('stepper') private myStepper: MatStepper;
    totalStepsCount: number;
  
    public steps: StepPage[];
  
    constructor(private stepsService: StepPagesService) { 
      this.steps = [
        new StepPage1Component,
        new StepPage2Component,
        new StepPage3Component
      ]
    }
  </code></pre>
  <p>Markup:</p>
  <pre><code>&lt;mat-horizontal-stepper #stepper&gt;
    &lt;mat-step *ngFor='let step of steps'&gt;
      &lt;app-step-page-wrapper item='step'&gt;&lt;/app-step-page-wrapper&gt;
    &lt;/mat-step&gt;     
  &lt;/mat-horizontal-stepper&gt;
  
  &lt;!-- second option --&gt;
  &lt;div&gt;
    &lt;button (click)=&quot;goBack(stepper)&quot; type=&quot;button&quot; [disabled]=&quot;stepper.selectedIndex === 0&quot;&gt;Back&lt;/button&gt;
    &lt;button (click)=&quot;goForward(stepper)&quot; type=&quot;button&quot;
      [disabled]=&quot;stepper.selectedIndex === stepper._steps.length-1&quot;&gt;Next&lt;/button&gt;
  
    &lt;!-- using totalStepsCount --&gt;
    &lt;!-- &lt;button (click)=&quot;goForward(stepper)&quot; type=&quot;button&quot; [disabled]=&quot;stepper.selectedIndex === totalStepsCount-1&quot;&gt;Next&lt;/button&gt; --&gt;
  &lt;/div&gt;
  </code></pre>
  <p>So in markup above, I have the <code>ngFor</code> that I am having problems with.</p>
  <p>The wrapper is as follows...</p>
  <pre><code>import { Component, OnInit, Input, ViewChild, ComponentFactoryResolver } from '@angular/core';
  import { directiveDef } from '@angular/core/src/view';
  import { PageDirective } from '../page.directive';
  
  @Component({
    selector: 'app-step-page-wrapper',
    template: '&lt;ng-template pageDirective&gt;&lt;/ng-template&gt;',
  })
  export class StepPageWrapperComponent implements OnInit {
    @Input() item?: any;
    @ViewChild(PageDirective) pageHost: PageDirective;
  
    constructor(private componentFactoryResolver: ComponentFactoryResolver) { }
  
    ngOnInit() {
      if (this.item == undefined) {
        console.error('Item undefined');
        return 
      }
  
      const componentFactory = this.componentFactoryResolver.resolveComponentFactory(this.item);
      const viewContainerRef = this.pageHost.viewContainerRef;
      viewContainerRef.clear();
      const componentRef = viewContainerRef.createComponent(componentFactory);
    }
  }
  </code></pre>
  <p>and finally the directive it is using is..</p>
  <pre><code>import { Directive, ViewContainerRef } from '@angular/core';
  
  @Directive({
    selector: '[pageDirective]'
  })
  export class PageDirective {
  
    constructor(public viewContainerRef: ViewContainerRef) { }
  }
  </code></pre>
  <p>So, I am trying to use the <code>StepPageWrapperComponent</code> to take each component as an input (<code>item</code>), and then use the <code>componentFactoryResolver</code> to create the conponent and then &quot;attach&quot; it to the directive in the template, ie <code>pageDirective</code> in <code>&lt;ng-template pageDirective&gt;&lt;/ng-template&gt;</code></p>
  <p>However, when I run this, I get the following error..</p>
  <pre><code>        ERROR Error: No component factory found for step. Did you add it to @NgModule.entryComponents?
          at noComponentFactoryError (core.js:9877)
          at CodegenComponentFactoryResolver.push../node_modules/@angular/core/fesm5/core.js.CodegenComponentFactoryResolver.resolveComponentFactory (core.js:9915)
          at StepPageWrapperComponent.push../src/app/step-page-wrapper/step-page-wrapper.component.ts.StepPageWrapperComponent.ngOnInit (step-page-wrapper.component.ts:21)
          at checkAndUpdateDirectiveInline (core.js:22099)
          at checkAndUpdateNodeInline (core.js:23363)
          at checkAndUpdateNode (core.js:23325)
          at debugCheckAndUpdateNode (core.js:23959)
          at debugCheckDirectivesFn (core.js:23919)
          at Object.eval [as updateDirectives] (WizardStepperComponent.html:3)
          at Object.debugUpdateDirectives [as updateDirectives] (core.js:23911)
  </code></pre>
  <p>If I put a break point in <code>StepPageWrapperComponent</code>, <code>this.item</code> just seems to be a string!</p>
  <p><a href="https://i.stack.imgur.com/uIeX4.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/uIeX4.png" alt="enter image description here" /></a></p>
  <p>So, this string &quot;step&quot; is meant to be the ngFor variable...</p>
  <p><a href="https://i.stack.imgur.com/Mt1bj.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Mt1bj.png" alt="enter image description here" /></a></p>
  <p>But it is just coming in as a string, rather than the component.</p>
  <p>Does anyone have any ideas on what I am doing wrong here, or even if there is a better way of doing this?</p>
  <p>For any more details the source for this sample is can be cloned from <a href="https://github.com/pjc2007/wizard-stepper1.git" rel="nofollow noreferrer">https://github.com/pjc2007/wizard-stepper1.git</a></p>
  <h2>Update 30 Aug 19</h2>
  <p>The reason the input was not working was I forgot the square brackets when passing the variable to the input.. ie I had</p>
  <pre><code>&lt;app-step-page-wrapper item='step'&gt;&lt;/app-step-page-wrapper&gt;
  </code></pre>
  <p>instead of</p>
  <pre><code>    &lt;app-step-page-wrapper [item]='step'&gt;&lt;/app-step-page-wrapper&gt;
  </code></pre>
  <p>I now have the component as the input for <code>StepPageWrapperComponent</code> as expected.</p>
  <p><a href="https://i.stack.imgur.com/Xct7f.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Xct7f.png" alt="enter image description here" /></a></p>
  <p>So, my problem now is the following error that is thrown  when executing the line <code>const componentFactory=this.componentFactoryResolver.resolveComponentFactory(this.item)</code></p>
  <pre><code>ngComponent: StepPage1Component {}
  message: &quot;No component factory found for [object Object]. Did you add it to @NgModule.entryComponents?&quot;
  stack: &quot;Error: No component factory found for [object Object]. Did you add it to @NgModule.entryComponents?↵    at noComponentFactoryError (http://localhost:4200/vendor.js:71338:17)↵    at CodegenComponentFactoryResolver.push../node_modules/@angular/core/fesm5/core.js.CodegenComponentFactoryResolver.resolveComponentFactory (http://localhost:4200/vendor.js:71376:19)↵    at StepPageWrapperComponent.push../src/app/step-page-wrapper/step-page-wrapper.component.ts.StepPageWrapperComponent.ngOnInit (http://localhost:4200/main.js:244:66)↵    at checkAndUpdateDirectiveInline (http://localhost:4200/vendor.js:83560:19)↵    at checkAndUpdateNodeInline (http://localhost:4200/vendor.js:84824:20)↵    at checkAndUpdateNode (http://localhost:4200/vendor.js:84786:16)↵    at debugCheckAndUpdateNode (http://localhost:4200/vendor.js:85420:38)↵    at debugCheckDirectivesFn (http://localhost:4200/vendor.js:85380:13)↵    at Object.eval [as updateDirectives] (ng:///AppModule/WizardStepperComponent.ngfactory.js:16:5)↵    at Object.debugUpdateDirectives [as updateDirectives] (http://localhost:4200/vendor.js:85372:21)&quot;
  __proto__: Object
  </code></pre>
  <p>I <strong>do</strong> have this as an entryComponent</p>
  <p>ie</p>
  <pre><code>@NgModule({
    declarations: [
      AppComponent,
      WizardStepperComponent,
      StepPage1Component,
      StepPage2Component,
      StepPage3Component,
      PageDirective,
      StepPageWrapperComponent
    ],
    imports: [
      BrowserModule,
      BrowserAnimationsModule,
      MatStepperModule,
      MatInputModule,
      MatButtonModule,
      MatAutocompleteModule
    ],
    providers: [],
    bootstrap: [AppComponent],
    entryComponents: [
      StepPage1Component,
      StepPage2Component,
      StepPage3Component,
      StepPageWrapperComponent
    ]
  </code></pre>
  <h2>Update 30 Aug 19</h2>
  <p>Stepping into <code>this.componentFactoryResolver.resolveComponentFactory</code>, I see the following...</p>
  <p><a href="https://i.stack.imgur.com/IZWWg.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/IZWWg.png" alt="enter image description here" /></a></p>
  <p>So the component seems to be in the map, but the map.get is returning undefined?</p>