Angular CDK: How to set Inputs in a ComponentPortal

angular, angular-cdk, angular-material2

Solution

You can create a custom injector and inject it to the component portal you create.

createInjector(dataToPass): PortalInjector {
    const injectorTokens = new WeakMap();
    injectorTokens.set(CONTAINER_DATA, dataToPass);
    return new PortalInjector(this._injector, injectorTokens);
}

`CONTAINER_DATA` is a custom injector (`InjectorToken`) created by -

export const CONTAINER_DATA = new InjectionToken<{}>('CONTAINER_DATA');

To consume created injector, use -

let containerPortal = new ComponentPortal(ComponentToPort, null, this.createInjector({
          data1,
          data2
        }));

overlay.attach(containerPortal);

`overlay` is an instance of `OverlayRef` (Which is Portal Outlet)

Inside `ComponentToPort`, you will need to inject the created injector -

@Inject(CONTAINER_DATA) public componentData: any

More on this here.

Problem

I would like to use the new Portal from material CDK to inject dynamic content in multiple part of a form. I have a complex form structure and the goal is to have a form that specify multiple place where sub components could (or not) inject templates. Maybe the CDK Portal is not the best solution for this? I tried something but I am sure it is not the way of doing: https://stackblitz.com/edit/angular-yuz1kg I tried also with `new ComponentPortal(MyPortalComponent)` but how can we set Inputs on it ? Usually is something like `componentRef.component.instance.myInput`

Original source