diff --git a/modules/@angular/compiler/src/template_parser/template_parser.ts b/modules/@angular/compiler/src/template_parser/template_parser.ts
index 30e1cf06f7..fe518c87a3 100644
--- a/modules/@angular/compiler/src/template_parser/template_parser.ts
+++ b/modules/@angular/compiler/src/template_parser/template_parser.ts
@@ -13,7 +13,7 @@ import {CompileDirectiveMetadata, CompilePipeMetadata, CompileTokenMetadata, rem
import {AST, ASTWithSource, BindingPipe, EmptyExpr, Interpolation, ParserError, RecursiveAstVisitor, TemplateBinding} from '../expression_parser/ast';
import {Parser} from '../expression_parser/parser';
import {ListWrapper, SetWrapper, StringMapWrapper} from '../facade/collection';
-import {isBlank, isPresent} from '../facade/lang';
+import {isBlank, isPresent, isString} from '../facade/lang';
import {HtmlParser} from '../i18n/html_parser';
import {Identifiers, identifierToken} from '../identifiers';
import * as html from '../ml_parser/ast';
@@ -746,9 +746,15 @@ class TemplateParseVisitor implements html.Visitor {
targetPropertyAsts: BoundElementPropertyAst[]) {
if (isPresent(hostProps)) {
StringMapWrapper.forEach(hostProps, (expression: string, propName: string) => {
- const exprAst = this._parseBinding(expression, sourceSpan);
- targetPropertyAsts.push(
- this._createElementPropertyAst(elementName, propName, exprAst, sourceSpan));
+ if (isString(expression)) {
+ const exprAst = this._parseBinding(expression, sourceSpan);
+ targetPropertyAsts.push(
+ this._createElementPropertyAst(elementName, propName, exprAst, sourceSpan));
+ } else {
+ this._reportError(
+ `Value of the host property binding "${propName}" needs to be a string representing an expression but got "${expression}" (${typeof expression})`,
+ sourceSpan);
+ }
});
}
}
@@ -758,7 +764,13 @@ class TemplateParseVisitor implements html.Visitor {
targetEventAsts: BoundEventAst[]) {
if (isPresent(hostListeners)) {
StringMapWrapper.forEach(hostListeners, (expression: string, propName: string) => {
- this._parseEvent(propName, expression, sourceSpan, [], targetEventAsts);
+ if (isString(expression)) {
+ this._parseEvent(propName, expression, sourceSpan, [], targetEventAsts);
+ } else {
+ this._reportError(
+ `Value of the host listener "${propName}" needs to be a string representing an expression but got "${expression}" (${typeof expression})`,
+ sourceSpan);
+ }
});
}
}
diff --git a/modules/@angular/compiler/test/template_parser/template_parser_spec.ts b/modules/@angular/compiler/test/template_parser/template_parser_spec.ts
index 604af8fe2c..ef0ebaec41 100644
--- a/modules/@angular/compiler/test/template_parser/template_parser_spec.ts
+++ b/modules/@angular/compiler/test/template_parser/template_parser_spec.ts
@@ -313,6 +313,30 @@ Can't bind to 'invalidProp' since it isn't a known property of 'my-component'.
expect(console.warnings.length).toEqual(0);
});
+ it('should throw descriptive error when a host binding is not a string expression', () => {
+ var dirA = CompileDirectiveMetadata.create({
+ selector: 'broken',
+ type: new CompileTypeMetadata({moduleUrl: someModuleUrl, name: 'DirA'}),
+ host: {'[class.foo]': null}
+ });
+
+ expect(() => { parse('