fix(NgClass): throw a descriptive error when CSS class is not a string (#12662)

Fixes #12586
This commit is contained in:
Pawel Kozlowski 2016-11-07 21:23:31 +01:00 committed by vikerman
parent 22c021c57f
commit f3793b5953
2 changed files with 17 additions and 5 deletions

View File

@ -9,7 +9,7 @@
import {CollectionChangeRecord, Directive, DoCheck, ElementRef, Input, IterableDiffer, IterableDiffers, KeyValueChangeRecord, KeyValueDiffer, KeyValueDiffers, Renderer} from '@angular/core'; import {CollectionChangeRecord, Directive, DoCheck, ElementRef, Input, IterableDiffer, IterableDiffers, KeyValueChangeRecord, KeyValueDiffer, KeyValueDiffers, Renderer} from '@angular/core';
import {isListLikeIterable} from '../facade/collection'; import {isListLikeIterable} from '../facade/collection';
import {isPresent} from '../facade/lang'; import {isPresent, stringify} from '../facade/lang';
/** /**
* @ngModule CommonModule * @ngModule CommonModule
@ -108,8 +108,14 @@ export class NgClass implements DoCheck {
} }
private _applyIterableChanges(changes: any): void { private _applyIterableChanges(changes: any): void {
changes.forEachAddedItem( changes.forEachAddedItem((record: CollectionChangeRecord) => {
(record: CollectionChangeRecord) => this._toggleClass(record.item, true)); if (typeof record.item === 'string') {
this._toggleClass(record.item, true);
} else {
throw new Error(
`NgClass can only toggle CSS classes expressed as strings, got ${stringify(record.item)}`);
}
});
changes.forEachRemovedItem( changes.forEachRemovedItem(
(record: CollectionChangeRecord) => this._toggleClass(record.item, false)); (record: CollectionChangeRecord) => this._toggleClass(record.item, false));

View File

@ -8,7 +8,6 @@
import {Component} from '@angular/core'; import {Component} from '@angular/core';
import {ComponentFixture, TestBed, async} from '@angular/core/testing'; import {ComponentFixture, TestBed, async} from '@angular/core/testing';
import {beforeEach, describe, expect, it} from '@angular/core/testing/testing_internal';
export function main() { export function main() {
describe('binding to CSS class list', () => { describe('binding to CSS class list', () => {
@ -187,6 +186,13 @@ export function main() {
getComponent().arrExpr = ['foo bar baz foobar']; getComponent().arrExpr = ['foo bar baz foobar'];
detectChangesAndExpectClassName('foo bar baz foobar'); detectChangesAndExpectClassName('foo bar baz foobar');
})); }));
it('should throw with descriptive error message when CSS class is not a string', () => {
fixture = createTestComponent(`<div [ngClass]="['foo', {}]"></div>`);
expect(() => fixture.detectChanges())
.toThrowError(
/NgClass can only toggle CSS classes expressed as strings, got \[object Object\]/);
});
}); });
describe('expressions evaluating to sets', () => { describe('expressions evaluating to sets', () => {
@ -348,4 +354,4 @@ class TestComponent {
function createTestComponent(template: string): ComponentFixture<TestComponent> { function createTestComponent(template: string): ComponentFixture<TestComponent> {
return TestBed.overrideComponent(TestComponent, {set: {template: template}}) return TestBed.overrideComponent(TestComponent, {set: {template: template}})
.createComponent(TestComponent); .createComponent(TestComponent);
} }