4

I have been trying to dynamically load an external angular module (AppA) into another angular application (AppB) at runtime.

AppA is created with angular-cli, compiled with ngc and packaged with rollupjs. Perfect.

I have two cases:

  • AppB completely configured with SystemJS. It can load AppA using System.import instruction without problems.
  • AppB created with angular-cli. There has not been a way to make it work.

In the second case, I have two subcases:

  • I tried to import on this way but it does not let compile because it does not find the module in its own application.

declare var System;

System.import('http://url-module.umd.js')

But when trying to load the previously compiled library with rollupjs in umd.js format, the following error appears:

  • The other option has been to implement the following code:

// ANGULAR
import { Component, ComponentFactory, ComponentFactoryResolver, Injector, Input, NgModuleFactory, NgModuleRef, OnInit, ViewContainerRef, ViewChild } from '@angular/core';

// CLASSES
import { MetadataModule } from '../../classes/metadata-module';
import { ModuleData } from '../../classes/module-data';

// SERVICES
import { ModuleService } from '../../services/module.service';

@Component({
  selector: 'dynamic-component-loader',
  template: ''
})
export class DynamicLoaderComponent implements OnInit {

  @Input('moduleData') moduleData: ModuleData;
  private factorySuffix: string = 'NgFactory';
  private pluginEntryPointToken: string = 'PLUGIN_ENTRY_POINT';

  constructor(
    private injector: Injector,
    private _resolver: ComponentFactoryResolver,
    private moduleService: ModuleService,
    private viewRef: ViewContainerRef,
  ) { }

  ngOnInit() {
    this.moduleService.loadMetadataFile(this.moduleData.metadata)
      .subscribe((metadataModule: MetadataModule) => {
        const script: HTMLScriptElement = document.createElement('script');
        script.src = this.moduleData.library;
        script.onload = () => {
          console.log('script loaded');
          const moduleFactory: NgModuleFactory<any> = window[metadataModule.name][metadataModule.moduleName + this.factorySuffix];
          const moduleRef: NgModuleRef<any> = moduleFactory.create(this.injector);
          const compType = moduleRef.injector.get(this.pluginEntryPointToken);
          const compFactory: ComponentFactory<any> = moduleRef.componentFactoryResolver.resolveComponentFactory(compType);
          this.viewRef.createComponent(compFactory);
        };
        document.head.appendChild(script);
      });

  }

}

but when executing it, it returns the following error that I have not been able to solve.

ERROR Error: StaticInjectorError[RendererFactory2]: 
  StaticInjectorError[RendererFactory2]: 
    NullInjectorError: No provider for RendererFactory2!
    at _NullInjector.get (core.js:923)
    at resolveToken (core.js:1211)
    at tryResolveToken (core.js:1153)
    at StaticInjector.get (core.js:1024)
    at resolveToken (core.js:1211)
    at tryResolveToken (core.js:1153)
    at StaticInjector.get (core.js:1024)
    at resolveNgModuleDep (core.js:10585)
    at NgModuleRef_.get (core.js:11806)
    at Object.debugCreateRootView [as createRootView] (scripts.bundle.js:35597)
    at ____________________Elapsed_12_ms__At__Wed_Nov_15_2017_16_58_27_GMT_0100__CET_ ()
    at Object.onScheduleTask (scripts.bundle.js:122)
    at ZoneDelegate.scheduleTask (zone.js:405)
    at Object.onScheduleTask (zone.js:301)
    at ZoneDelegate.scheduleTask (zone.js:405)
    at Zone.scheduleTask (zone.js:236)
    at Zone.scheduleEventTask (zone.js:262)
    at HTMLScriptElement.eval [as addEventListener] (zone.js:1832)
    at HTMLScriptElement.desc.set [as onload] (zone.js:1216)
    at ____________________Elapsed_13_ms__At__Wed_Nov_15_2017_16_58_27_GMT_0100__CET_ ()

Code of second subcase is here github code

Any help will be appreciated

Dani Andújar
  • 1,116
  • 1
  • 12
  • 15
  • _But when trying to load the previously compiled library with rollupjs in umd.js format_ - is it `AppA` or `AppB`? Can angular-cli bundle UMD modules with rollup? Also, which app are you importing it? – Max Koretskyi Nov 16 '17 at 06:22
  • **AppB** imports / loads **AppA**, where **AppA** is compiled with **ngc** and packaged with **rollupjs**. In the repo AppA is **ViewA** and AppB is **frontend**. @AngularInDepth.com – Dani Andújar Nov 16 '17 at 07:36
  • executed `npm start`, Angular CLI project is open, nothing is loaded – Max Koretskyi Nov 16 '17 at 11:04
  • @AngularInDepth.com Follow this instructions in this order (remember that you need to have a CROS pluggin for chrome to enable requests. The servers are listening in different ports of the application itself): Terminal session 1 cd backend npm install npm start server listening on port 5000 Terminal session 2 cd serverA npm install npm start server listening on port 5001 Terminal session 3 cd frontend npm install npm start Go to http://localhost:4200 and click button ViewA. Open browser console and look the error. – Dani Andújar Nov 16 '17 at 13:53
  • too many steps, sorry, don't have time – Max Koretskyi Nov 16 '17 at 17:18
  • @AngularInDepth.com do you know how to solve this error? – Dani Andújar Nov 17 '17 at 09:08
  • sorry, don't have time to look at it – Max Koretskyi Nov 17 '17 at 09:28
  • @AngularInDepth.com : Am facing the same error. This used to work earlier with angular version 5.0.0, but does not work with 5.0.2 – cvraman Nov 21 '17 at 10:23
  • @cvraman would you mind to share the solution for angular 5.0? – Dani Andújar Nov 21 '17 at 10:32
  • I have a similar issue on this thread: https://stackoverflow.com/questions/47342589/angular5-dynamic-component-loading-containing-material-component-in-template. You can take a look at this reproduction of the bug: https://github.com/thyb/repro-dynamic-loading - If it may help someone to reproduce the issue.. :) – Thibaud Arnault Dec 05 '17 at 18:57
  • Any one got this working, I'm hitting the same brick in the road here. Created a seperate question for it ; https://stackoverflow.com/questions/50149016/load-new-modules-dynamically-in-run-time-with-angular-cli-angular-5 – Lars Meijdam May 03 '18 at 07:36
  • I created a repository on github with a solution which might help. It uses Angular 6 libraries and 1 base applications which load up the UMD bundled libraries lazily; https://github.com/lmeijdam/angular-umd-dynamic-example If you have any suggestions, please feel free to add! – Lars Meijdam May 09 '18 at 06:37
  • @LarsMeijdam I'm very interested in taking a look at your repo. But, the link gives me a 404. Is there a way I can get into the repo? Thanks! – mgm87 May 17 '18 at 03:25
  • @mgm87 I actually needed to put it offline due to company policy... sadly. If you're keen in reviewing, please let me know at lmeijdam90@gmail.com and we'll look what's possible – Lars Meijdam May 17 '18 at 05:42

0 Answers0