jeeves90 jeeves90 - 2 months ago 168
AngularJS Question

Using ng2-bootstrap with Angular 2 RC 6 - can't bind to can't bind to [...] since it isn't a known property of [...]

I'm just getting started with Angular 2 (RC 6) and I've run into a problem with using ng2-bootstrap. I know RC 6 came out very recently, but I think it's just something I'm doing wrong than a bug.

I'm trying to recreate a basic demo from the ng2-boostrap demo pages, specifically the typeahead box demo. Here's my

AppModule
:

import { NgModule, Component, ViewChild } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AlertModule, TypeaheadModule, Ng2BootstrapModule } from 'ng2-bootstrap/ng2-bootstrap';
import { FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';

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


@NgModule({
imports: [ BrowserModule, Ng2BootstrapModule, AlertModule, TypeaheadModule, FormsModule ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ],
})
export class AppModule { }


Then the app.component:

import { Component, ViewChild } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';

@Component({
selector: 'my-app',
templateUrl: 'app/main.html'
})
export class AppComponent {

public customSelected:string = '';
public selected:string = '';
public dataSource:Observable<any>;
public asyncSelected:string = '';
public typeaheadLoading:boolean = false;
public typeaheadNoResults:boolean = false;
public states:Array<string> = ['Alabama', 'Alaska', 'Arizona', 'Arkansas',
'California', 'Colorado',
'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii', 'Idaho',
'Illinois', 'Indiana', 'Iowa',
'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts',
'Michigan', 'Minnesota',
'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire',
'New Jersey', 'New Mexico',
'New York', 'North Dakota', 'North Carolina', 'Ohio', 'Oklahoma', 'Oregon',
'Pennsylvania', 'Rhode Island',
'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont',
'Virginia', 'Washington',
'West Virginia', 'Wisconsin', 'Wyoming'];
public statesComplex:Array<any> = [
{id: 1, name: 'Alabama'}, {id: 2, name: 'Alaska'}, {id: 3, name: 'Arizona'},
{id: 4, name: 'Arkansas'}, {id: 5, name: 'California'}];

public constructor() {
this.dataSource = Observable.create((observer:any) => {
// Runs on every search
observer.next(this.asyncSelected);
}).mergeMap((token:string) => this.getStatesAsObservable(token));
}

public getStatesAsObservable(token:string):Observable<any> {
let query = new RegExp(token, 'ig');

return Observable.of(
this.statesComplex.filter((state:any) => {
return query.test(state.name);
})
);
}

public changeTypeaheadLoading(e:boolean):void {
this.typeaheadLoading = e;
}

public changeTypeaheadNoResults(e:boolean):void {
this.typeaheadNoResults = e;
}

public typeaheadOnSelect(e:any):void {
console.log('Selected value: ', e.item);
}
}


The relevant snippet of HTML:

<input [typeahead]="states"
(typeaheadOnSelect)="typeaheadOnSelect($event)"
[typeaheadOptionsLimit]="7"
[typeaheadOptionField]="'name'"
[typeaheadMinLength]="0"
placeholder="Typeahead inside a form"
class="form-control">


The error that I'm getting is this:

Can't bind to 'typeahead' since it isn't a known property of 'input'. ("
<h4>Typeahead inside a form</h4>

<input [ERROR ->][typeahead]="states"
(typeaheadOnSelect)="typeaheadOnSelect($event)"
[typeaheadOp"): AppComponent@12:9
Can't bind to 'typeaheadOptionsLimit' since it isn't a known property of 'input'. ("
[....]


Finally, here's my system js config:

(function (global) {
System.config({
paths: {
// paths serve as alias
'npm:': 'node_modules/'
},
// map tells the System loader where to look for things
map: {
// our app is within the app folder
app: 'app',

// angular bundles
'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common/bundles/common.umd.js',
'@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
'@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'@angular/http': 'npm:@angular/http/bundles/http.umd.js',
'@angular/router': 'npm:@angular/router/bundles/router.umd.js',
'@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',

// other libraries
'rxjs': 'npm:rxjs',
'angular2-in-memory-web-api': 'npm:angular2-in-memory-web-api',
'moment': 'node_modules/moment/moment.js',
'ng2-bootstrap': 'node_modules/ng2-bootstrap'
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
app: { main: './main.js', defaultExtension: 'js' },
rxjs: { defaultExtension: 'js' },
'angular2-in-memory-web-api': { main: './index.js', defaultExtension: 'js' },
'ng2-bootstrap': {defaultJSExtensions: true}
}
});
})(this);


Does anyone have any suggestions? As far as I can see at the moment ng2-bootstrap should be loaded in SystemJS, the imports I think are correct in the AppModule and everything should work from there, but I'm obviously missing something.

Answer

Typeahead is either not being found or matched. I suspect it's not being matched.

According to the documentation here (https://valor-software.com/ng2-bootstrap/#/typeahead) the selector for typeahead needs an [(ngModel)] binding which looks like it's missing.

Bind the string in your component to ngModel like <input [(ngModel)]="selected" ... > and then the Typeahead selector should kick in.

Comments