Angular 2 @NgModule.scheme, what does it actually do?

When working with Angular 2 components, sometimes I came up with below error.

1

And googling tells me to set @NgModule.scheme as to CUSTOM_ELEMENTS_SCHEMA which resolve this issue.

So, for what purpose this scheme option is and what does it actually tells the Angular?

The NgModule’s scheme property tells the Angular compiler the type of component it wants to expect from the template. The available schema options are,

  1. CUSTOM_ELEMENTS_SCHEME.
  2. NO_ERRORS_SCHEME.

Default

By default, the compiler will check for Angular components in its template. When the selector is not matched with any of its declarations then it will check for the value of schema property.

If the selector, you used, is an Angular component and still you are getting this issue then you should double check whether you have properly imported the directive/component in the declarations of NgModule as follows.

@Component({
    selector: 'app-test',
    template: `Hello World`
})
export class TestComponent {
    constructor(){}
}

import { AppComponent, TestComponent }
from './app.component';

@NgModule({
  declarations: [
    AppComponent,
    TestComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

CUSTOM_ELEMENTS_SCHEME

This tells the compiler to allow any type of custom element in its template. The custom element should have hypen(-) so it’s attributes.

This helps to incorporate Web components other than Angular component in the application.

import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';

@NgModule({
  . . . .
  bootstrap: [AppComponent],
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class AppModule { }

NO_ERRORS_SCHEME
Its simple as the name implies it will not show error when there is an unknown selector in the template.

import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';

@NgModule({
  . . . .
  bootstrap: [AppComponent],
  schemas: [NO_ERRORS_SCHEMA]
})
export class AppModule { }

.

Happy debugging.. 🙂

Advertisements

Angular 2 – How to get template reference variable or directive instance inside component

In this post let us see how to get Angular 2 directive/child component instance inside the parent component class.

ViewChild in action
The ViewChild decorator can be used to achieve this requirement.
The ViewChild accepts either the directive type or the template reference variable as argument and set the directive instance to the target property after the view get initiated.

@Component({
selector: 'child-cmp',
template: '

child

'
})
class ChildCmp {
doSomething() {}
}
@Component({
selector: 'some-cmp',
template: '<child-cmp></child-cmp>',
directives: [ChildCmp]
})
class SomeCmp {
@ViewChild(ChildCmp) child:ChildCmp;
ngAfterViewInit() {
// child is set
this.child.doSomething();
}
}

The ViewChild will set the target property once the component view get rendered hence accessing the property before the view get initiated will return inappropriate result.

You can use the ngViewAfterInit lifecycle hook to identify the view initialization.

Argument as Directive type vs template variable
Using argument as template variable ViewChild is best from my point of view as it will provide access to specific directive instance when having more than one directive in the template.

@Component({
selector: 'some-cmp',
template: '<child-cmp #child></child-cmp>',
directives: [ChildCmp]
})
class SomeCmp {
@ViewChild('child') child:ChildCmp;
ngAfterViewInit() {
// child is set
this.child.doSomething();
}
}

Happy Scripting.. 🙂