1

In search of rendering MVC View in to angular 2 end up with this directive

export function createComponentFactory(compiler: Compiler, metadata: Component): Promise<ComponentFactory<any>> {
  const cmpClass = class DynamicComponent {};
  const decoratedCmp = Component(metadata)(cmpClass);

  @NgModule({ imports: [CommonModule, RouterModule], declarations: [decoratedCmp] })
  class DynamicHtmlModule { }

  return compiler.compileModuleAndAllComponentsAsync(DynamicHtmlModule)
    .then((moduleWithComponentFactory: ModuleWithComponentFactories<any>) => {
      return moduleWithComponentFactory.componentFactories.find(x => x.componentType === decoratedCmp);
    });
}

All working fine my View rendering as I wanted but after few seconds this Error pops.

enter image description here

my Component Code:

 import {
    Component,
    Directive,
    NgModule,
    Input,
    ViewContainerRef,
    Compiler,
    ComponentFactory,
    ModuleWithComponentFactories,
    ComponentRef,
    ReflectiveInjector, OnInit, OnDestroy, Type
} from '@angular/core';

import { RouterModule } from '@angular/router';
import { CommonModule } from '@angular/common';
import { Http } from "@angular/http";
import 'rxjs/add/operator/map';

export function createComponentFactory(compiler: Compiler, metadata: Component): Promise<ComponentFactory<any>> {   
    const cmpClass = class DynamicComponent { };
    const decoratedCmp = Component(metadata)(cmpClass);

    @NgModule({ imports: [CommonModule, RouterModule], declarations: [decoratedCmp] })
    class DynamicHtmlModule { }

    return compiler.compileModuleAndAllComponentsAsync(DynamicHtmlModule)
        .then((moduleWithComponentFactory: ModuleWithComponentFactories<any>) => {
            return moduleWithComponentFactory.componentFactories.find(x => x.componentType === decoratedCmp);
        });
}

@Directive({ selector: 'mvc-partial' })
export class RenderingViewDynamic implements OnInit, OnDestroy {
    html: string = '<p></p>';
    @Input() url: string;
    cmpRef: ComponentRef<any>;

    constructor(private vcRef: ViewContainerRef, private compiler: Compiler, private http: Http) { }

    ngOnInit() {
        this.http.get(this.url)
            .map(res => res.text())
            .subscribe(
            (html) => {
                this.html = html;
                if (!html) return;

                if (this.cmpRef) {
                    this.cmpRef.destroy();
                }

                const compMetadata = new Component({
                    selector: 'dynamic-html',
                    template: this.html,
                });

                createComponentFactory(this.compiler, compMetadata)
                    .then(factory => {
                        const injector = ReflectiveInjector.fromResolvedProviders([], this.vcRef.parentInjector);
                        this.cmpRef = this.vcRef.createComponent(factory, 0, injector, []);
                    });
            },
            err => console.log(err),
            () => console.log('MvcPartial complete')
            );

    }

    ngOnDestroy() {
        if (this.cmpRef) {
            this.cmpRef.destroy();
        }
    }
}

How could I over come this?

2
  • Please add code from RenderingViewDynamic.component.ts Commented Aug 22, 2017 at 4:29
  • updated @yurzui Commented Aug 22, 2017 at 4:39

1 Answer 1

0

I believe the problem is that you define a method that returns Promise<ComponentFactory<any>>, however inside the method you use find function which can return undefined:

The find() method returns the value of the first element in the array that satisfies the provided testing function. Otherwise undefined is returned.

So that is what TS complains about. Just modify the method call:

createComponentFactory(...): `Promise<ComponentFactory<any>> | Promise<undefined>` { ... }

Same thing here:

this.cmpRef = this.vcRef.createComponent(factory, 0, injector, []);
                    });

createComponent can only take ComponentFactory<C> but with your implementation it's possible that undefined can be passed. Maybe add a check that factory exists or if you're sure that it will never be undefined use non-null assertion operator.

Sign up to request clarification or add additional context in comments.

6 Comments

@MaximKorestskyi what you guess is right but your suggestion didn't resolve my issue same error occurs. Added my total code once check.
but with your implementation it's possible that undefined can be passed. Totally agreed . Maybe add a check that factory exists what you mean ?
factory having value, not undefined.
@k11k2, if (factory) { this.vcRef.createComponent( ....) }. What do you expect to happen if you pass undefined into createComponent?
target would be rendering my component with out exception so override that undefined make it smooth process.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.