0

I am trying to use a service to create dynamic components. I didn't have issues creating dynamic component when the code was in a component. When I move my code to a service I get an error about createComponent not found.

I have my function call in 'ngAfterViewInit', this was most people issues were when I looking for solutions. I been trying to figure out why my code doesn't work when I put it in a service. I have also tried making a director and that didn't work as well.

Here is the code in a stack blitz https://stackblitz.com/edit/angular-ikshag

The component and the service code is below.

app.component

import { GenService } from './gen.service';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements AfterViewInit {
  name = 'Angular';

 constructor(private gen: GenService) { }
  ngAfterViewInit() {
    this.gen.createComp("yo");
  }

}

service

import { Injectable, ComponentFactoryResolver, ViewChild,ViewContainerRef } from '@angular/core';
import { ChildComponent } from './child/child.component';

@Injectable({
  providedIn: 'root'
})
export class GenService {

  @ViewChild('container', { static: true }) newsHost: ViewContainerRef; //this allow the targeting needed to add component


  constructor(private componentFactoryResolver: ComponentFactoryResolver) { }


  createComp(message) {
    let componentFactory = this.componentFactoryResolver.resolveComponentFactory(ChildComponent);
    let componentRef = this.newsHost.createComponent(componentFactory);//adds it to the screen

  }//end of bot reply

}

child component is just the default that says it works.

5
  • I'm surprised to see a @ViewChild inside a service, it should be a component thing... Where did you find this ? Commented Sep 19, 2019 at 14:13
  • @Random i can't even remember the site i found some of this from. I think the code i found was some angular 2... so not 100% helpful. I am new to angular as well. Been trying to make a service where I can call it to make dynamic components. I haven't had any luck to find someone else using a service. Commented Sep 19, 2019 at 14:23
  • Try moving the @ViewChild in your AppComponent, giving it as a parameter to the service (this.gen.createComp("yo", this.newsHost)) Commented Sep 19, 2019 at 14:32
  • Sadly that didn't help. stackblitz.com/edit/angular-ikshag Commented Sep 19, 2019 at 14:43
  • 1
    malcoded.com/posts/angular-dynamic-components This seemed to work Commented Sep 19, 2019 at 15:52

2 Answers 2

1

This is not that simple. The topic you are reading (angular-dynamic-components) is quite long.

Have a look to src/app/dialog/insertion.directive.ts, which is then refered in the ng-template using its selector (whereas you used a container selector which does not map to any angular directive).
This directive has viewContainerRef injected, which is what is used to have access to the method createComponent. The ViewChild is quite more complex too: @ViewChild(InsertionDirective) insertionPoint: InsertionDirective.

So the steps you have to do are:

  1. Make a Directive as stated in the blog
  2. Use its selector in the <ng-template> tag
  3. Update your @ViewChild using your directive class
  4. access viewContainerRef of your directive (which has to be public) to use createComponent method
Sign up to request clarification or add additional context in comments.

Comments

0

malcoded.com/posts/angular-dynamic-components This seemed to work – Bratchan Sep 19, 2019

Search let componentFactory = this.componentFactoryResolver.resolveComponentFactory(xxxxx); in Bratchan's link. Use resolveComponentFactory, beforecreateComponent.

And about createComponent, Bratchan's link works on angular 10.x.x. If your package.json show your project angular version is 14.x.x, you maybe need to see here

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.