3

I am new in angular 6.

I am using ngComponentOutlet in a for loop

I want to know how can I pass the data to my child component

My HTML

<div *ngFor="let item of items">
    <ng-container *ngComponentOutlet="currentComponent"></ng-container>
</div>

My parent component who decides which component to chose

export class MyParentComponent implements OnInit {

 constructor(private route: ActivatedRoute, private commonService: CommonService) { }

 dynamicComponents =  {
  'firstchild': {
   '1': FirstchildComponent
  }
 };

 currentComponent: any;
 items: any;

 ngOnInit() {
    // To get data from resolver
  const routeResult = this.route.snapshot.data.data.result;
  this.items = routeResult.items;
    
    // select child component at basis of route
  const routeParams = this.route.snapshot.params;
  this.currentComponent = this.dynamicComponents[routeParams.pageName][routeParams.templateType];
 }
}

My child component

export class FirstchildComponent implements OnInit {
 @Input() magazineData: any[];
 constructor() { }

 ngOnInit() {
 }
}

So I want to pass item (single item of loop) to FirstchildComponent as a input

How can I do it?

I have checked with Injector

But as I am new, I don't really understand how injector works

Kiran Shinde
  • 5,732
  • 4
  • 24
  • 41
  • Possible duplicate of [angular 4+ assign @Input for ngComponentOutlet dynamically created component](https://stackoverflow.com/questions/42522633/angular-4-assign-input-for-ngcomponentoutlet-dynamically-created-component) – Florian Nov 29 '18 at 15:20
  • have you looked at this? https://v6.angular.io/tutorial/toh-pt3 – Michael Henderson Nov 29 '18 at 15:40
  • https://stackoverflow.com/questions/48188151/angular-5-dynamic-component-creation-with-constructor/48188791#48188791 Instead of `BasicProject` you can use any token – yurzui Nov 29 '18 at 15:43

2 Answers2

10

As you already had pointed out that you need to use the Injector which will provide all essential dependency data.

MyParentComponent

@Component({...})
export class MyParentComponent  {

  constructor(private inj: Injector) {}

  createInjector(item){
    let injector = Injector.create([
      { provide: Item, useValue: item }
    ], this.inj);
    return injector;
  }
}

Item Class

You will be having the class for Item if not then create new one with all properties -

@Injectable()
export class Item{
   ...
}

html

<div *ngFor="let item of items">
    <ng-container *ngComponentOutlet="currentComponent; injector:createInjector(item)"></ng-container>
</div>

Dynamic Component

export class FirstchildComponent implements OnInit {
    @Input() magazineData: any[];
    constructor() { }

    ngOnInit(private item : Item) {  //<-- item content is here.
    }
}

Note : The code has be written directly on stackoverflow editor so there could be typo and syntactical error. Please correct yourself.

Sunil Singh
  • 11,001
  • 2
  • 27
  • 48
0

ViewContainerRef, ComponentFactoryResolver makes it easier than ngComponentOutlet when creating dynamic components.

Dynamic Component

Template -

<div #dynamicComponent></div>

TS - 
@ViewChild('dynamicComponent', { read: ViewContainerRef }) podViewContainerRef;
  constructor(private resolver: ComponentFactoryResolver) {
  }

  ngAfterViewInit() {
    let componentFactory;
    let componentRef;
    try {
      componentFactory = this.resolver.resolveComponentFactory(pod.component);
      componentRef = this.podViewContainerRef.createComponent(componentFactory);
      componentRef.instance.podInfo = this.podInfo;
    } catch (e) {
      console.log(e);
    }
  }
  • but I have a list of dynamicComponent: `@ViewChildren('dynamicComponent', { read: ViewContainerRef }) podViewContainerRefs;`. This gets me an array. I have, somehow, to pass data to that ng-container – Ionel Lupu Nov 13 '20 at 13:09