6

I'm experimenting with a custom renderer for Angular2.

I've set up an simple example project with a minimal Angular2 application (AppComponent) that I'd like to run on Node.js. I've implemented a custom DomAdapter and a custom Renderer (just a dummy that should log to the console), then I try to wire everything together in some custom bootstrap code.

Currently, I'm stuck with the following error message:

Error: No precompiled component AppComponent found
at new BaseException (/home/ralf/git/node-angular-example/node_modules/angular2/src/facade/exceptions.js:15:23)
at Compiler_.compileInHost (/home/ralf/git/node-angular-example/node_modules/angular2/src/core/linker/compiler.js:47:19)
at DynamicComponentLoader_.loadAsRoot (/home/ralf/git/node-angular-example/node_modules/angular2/src/core/linker/dynamic_component_loader.js:101:31)
at di_1.provide.useFactory (/home/ralf/git/node-angular-example/node_modules/angular2/src/core/application_ref.js:29:47)
at Injector._instantiate (/home/ralf/git/node-angular-example/node_modules/angular2/src/core/di/injector.js:763:27)
at Injector._instantiateProvider (/home/ralf/git/node-angular-example/node_modules/angular2/src/core/di/injector.js:714:25)
at Injector._new (/home/ralf/git/node-angular-example/node_modules/angular2/src/core/di/injector.js:703:21)
at InjectorInlineStrategy.getObjByKeyId (/home/ralf/git/node-angular-example/node_modules/angular2/src/core/di/injector.js:216:33)
at Injector._getByKeyDefault (/home/ralf/git/node-angular-example/node_modules/angular2/src/core/di/injector.js:899:37)
at Injector._getByKey (/home/ralf/git/node-angular-example/node_modules/angular2/src/core/di/injector.js:845:25)

Can somebody explain what this means and what's missing?

Update: As Tobias Bosch pointed out, the COMPILER_PROVIDERS were missing. However, after adding them I get another error:

Error: DI Exception
at NoProviderError.BaseException [as constructor] (/home/ralf/git/angular2-renderer-example/node_modules/angular2/src/facade/exceptions.js:15:23)
at NoProviderError.AbstractProviderError [as constructor] (/home/ralf/git/angular2-renderer-example/node_modules/angular2/src/core/di/exceptions.js:38:16)
at new NoProviderError (/home/ralf/git/angular2-renderer-example/node_modules/angular2/src/core/di/exceptions.js:74:16)
at Injector._throwOrNull (/home/ralf/git/angular2-renderer-example/node_modules/angular2/src/core/di/injector.js:854:19)
at Injector._getByKeyDefault (/home/ralf/git/angular2-renderer-example/node_modules/angular2/src/core/di/injector.js:905:21)
at Injector._getByKey (/home/ralf/git/angular2-renderer-example/node_modules/angular2/src/core/di/injector.js:845:25)
at Injector._getByDependency (/home/ralf/git/angular2-renderer-example/node_modules/angular2/src/core/di/injector.js:831:25)
at Injector._instantiate (/home/ralf/git/angular2-renderer-example/node_modules/angular2/src/core/di/injector.js:723:36)
at Injector._instantiateProvider (/home/ralf/git/angular2-renderer-example/node_modules/angular2/src/core/di/injector.js:714:25)
at Injector._new (/home/ralf/git/angular2-renderer-example/node_modules/angular2/src/core/di/injector.js:703:21)

Could you help me understanding this one? How can I tell which provider is missing?

Update 2: Turned out that an implementation of XHR was missing. Adding a shim fixed the issue. Now it's working.

2
  • Hi @ralfstx, have u had a chance to get this upgraded to ng4+ ? Commented Sep 13, 2017 at 17:42
  • 1
    @ChrisTarasovs no, I eventually gave up on using angular. Sorry. Commented Sep 22, 2017 at 7:33

1 Answer 1

5

this error occurs because you did not provide the COMPILER_PROVIDERS (see https://github.com/angular/angular/blob/e1bf3d33f8a1fa05a832b9b7ee1300ef9862fd0b/modules/angular2/platform/browser.ts#L31 where we set it when bootstrapping in the browser).

For an example of a custom renderer, see our DebugDomRenderer (https://github.com/angular/angular/blob/e1bf3d33f8a1fa05a832b9b7ee1300ef9862fd0b/modules/angular2/src/core/debug/debug_renderer.ts).

import {isPresent} from 'angular2/src/facade/lang';
import {
  Renderer,
  RootRenderer,
  RenderComponentType,
  RenderDebugInfo
} from 'angular2/src/core/render/api';
import {
  DebugNode,
  DebugElement,
  EventListener,
  getDebugNode,
  indexDebugNode,
  removeDebugNodeFromIndex
} from 'angular2/src/core/debug/debug_node';

export class DebugDomRootRenderer implements RootRenderer {
  constructor(private _delegate: RootRenderer) {}

  renderComponent(componentProto: RenderComponentType): Renderer {
    return new DebugDomRenderer(this, this._delegate.renderComponent(componentProto));
  }
}

export class DebugDomRenderer implements Renderer {
  constructor(private _rootRenderer: DebugDomRootRenderer, private _delegate: Renderer) {}

  renderComponent(componentType: RenderComponentType): Renderer {
    return this._rootRenderer.renderComponent(componentType);
  }

  selectRootElement(selector: string): any {
    var nativeEl = this._delegate.selectRootElement(selector);
    var debugEl = new DebugElement(nativeEl, null);
    indexDebugNode(debugEl);
    return nativeEl;
  }

  createElement(parentElement: any, name: string): any {
    var nativeEl = this._delegate.createElement(parentElement, name);
    var debugEl = new DebugElement(nativeEl, getDebugNode(parentElement));
    debugEl.name = name;
    indexDebugNode(debugEl);
    return nativeEl;
  }

  createViewRoot(hostElement: any): any { return this._delegate.createViewRoot(hostElement); }

  createTemplateAnchor(parentElement: any): any {
    var comment = this._delegate.createTemplateAnchor(parentElement);
    var debugEl = new DebugNode(comment, getDebugNode(parentElement));
    indexDebugNode(debugEl);
    return comment;
  }

  createText(parentElement: any, value: string): any {
    var text = this._delegate.createText(parentElement, value);
    var debugEl = new DebugNode(text, getDebugNode(parentElement));
    indexDebugNode(debugEl);
    return text;
  }

  projectNodes(parentElement: any, nodes: any[]) {
    var debugParent = getDebugNode(parentElement);
    if (isPresent(debugParent) && debugParent instanceof DebugElement) {
      nodes.forEach((node) => { debugParent.addChild(getDebugNode(node)); });
    }
    return this._delegate.projectNodes(parentElement, nodes);
  }

  attachViewAfter(node: any, viewRootNodes: any[]) {
    var debugNode = getDebugNode(node);
    if (isPresent(debugNode)) {
      var debugParent = debugNode.parent;
      if (viewRootNodes.length > 0 && isPresent(debugParent)) {
        var debugViewRootNodes = [];
        viewRootNodes.forEach((rootNode) => debugViewRootNodes.push(getDebugNode(rootNode)));
        debugParent.insertChildrenAfter(debugNode, debugViewRootNodes);
      }
    }
    return this._delegate.attachViewAfter(node, viewRootNodes);
  }

  detachView(viewRootNodes: any[]) {
    viewRootNodes.forEach((node) => {
      var debugNode = getDebugNode(node);
      if (isPresent(debugNode) && isPresent(debugNode.parent)) {
        debugNode.parent.removeChild(debugNode);
      }
    });
    return this._delegate.detachView(viewRootNodes);
  }

  destroyView(hostElement: any, viewAllNodes: any[]) {
    viewAllNodes.forEach((node) => { removeDebugNodeFromIndex(getDebugNode(node)); });
    return this._delegate.destroyView(hostElement, viewAllNodes);
  }

  listen(renderElement: any, name: string, callback: Function) {
    var debugEl = getDebugNode(renderElement);
    if (isPresent(debugEl)) {
      debugEl.listeners.push(new EventListener(name, callback));
    }
    return this._delegate.listen(renderElement, name, callback);
  }

  listenGlobal(target: string, name: string, callback: Function): Function {
    return this._delegate.listenGlobal(target, name, callback);
  }

  setElementProperty(renderElement: any, propertyName: string, propertyValue: any) {
    var debugEl = getDebugNode(renderElement);
    if (isPresent(debugEl) && debugEl instanceof DebugElement) {
      debugEl.properties.set(propertyName, propertyValue);
    }
    return this._delegate.setElementProperty(renderElement, propertyName, propertyValue);
  }

  setElementAttribute(renderElement: any, attributeName: string, attributeValue: string) {
    var debugEl = getDebugNode(renderElement);
    if (isPresent(debugEl) && debugEl instanceof DebugElement) {
      debugEl.attributes.set(attributeName, attributeValue);
    }
    return this._delegate.setElementAttribute(renderElement, attributeName, attributeValue);
  }

  /**
   * Used only in debug mode to serialize property changes to comment nodes,
   * such as <template> placeholders.
   */
  setBindingDebugInfo(renderElement: any, propertyName: string, propertyValue: string) {
    return this._delegate.setBindingDebugInfo(renderElement, propertyName, propertyValue);
  }

  /**
   * Used only in development mode to set information needed by the DebugNode for this element.
   */
  setElementDebugInfo(renderElement: any, info: RenderDebugInfo) {
    var debugEl = getDebugNode(renderElement);
    debugEl.setDebugInfo(info);
    return this._delegate.setElementDebugInfo(renderElement, info);
  }

  setElementClass(renderElement: any, className: string, isAdd: boolean) {
    return this._delegate.setElementClass(renderElement, className, isAdd);
  }

  setElementStyle(renderElement: any, styleName: string, styleValue: string) {
    return this._delegate.setElementStyle(renderElement, styleName, styleValue);
  }

  invokeElementMethod(renderElement: any, methodName: string, args: any[]) {
    return this._delegate.invokeElementMethod(renderElement, methodName, args);
  }

  setText(renderNode: any, text: string) { return this._delegate.setText(renderNode, text); }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks Tobias, I've added COMPILER_PROVIDERS, but now I get another error (see updated question). Could you help me with this one as well? Thanks for the pointer to the debug renderer, I'll also give this a try.
Fixed by adding a missing implementation of XHR. It was needed by the compiler. Now it's working. Thanks again!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.