diff --git a/src/lib/badge/badge.spec.ts b/src/lib/badge/badge.spec.ts
index 8933239d52c1..a06737df9b5a 100644
--- a/src/lib/badge/badge.spec.ts
+++ b/src/lib/badge/badge.spec.ts
@@ -11,10 +11,12 @@ describe('MatBadge', () => {
let badgeDebugElement: DebugElement;
beforeEach(fakeAsync(() => {
- TestBed.configureTestingModule({
- imports: [MatBadgeModule],
- declarations: [BadgeTestApp],
- }).compileComponents();
+ TestBed
+ .configureTestingModule({
+ imports: [MatBadgeModule],
+ declarations: [BadgeTestApp, PreExistingBadge, NestedBadge],
+ })
+ .compileComponents();
fixture = TestBed.createComponent(BadgeTestApp);
testComponent = fixture.debugElement.componentInstance;
@@ -184,6 +186,20 @@ describe('MatBadge', () => {
expect(badgeContent.hasAttribute('aria-label')).toBe(false);
});
+ it('should clear any pre-existing badges', () => {
+ const preExistingFixture = TestBed.createComponent(PreExistingBadge);
+ preExistingFixture.detectChanges();
+
+ expect(preExistingFixture.nativeElement.querySelectorAll('.mat-badge-content').length).toBe(1);
+ });
+
+ it('should not clear badge content from child elements', () => {
+ const preExistingFixture = TestBed.createComponent(NestedBadge);
+ preExistingFixture.detectChanges();
+
+ expect(preExistingFixture.nativeElement.querySelectorAll('.mat-badge-content').length).toBe(2);
+ });
+
});
/** Test component that contains a MatBadge. */
@@ -214,3 +230,27 @@ class BadgeTestApp {
badgeDescription: string;
badgeDisabled = false;
}
+
+
+@Component({
+ template: `
+
+ home
+ Pre-existing badge
+
+ `
+})
+class PreExistingBadge {
+}
+
+
+@Component({
+ template: `
+
+ home
+ Something
+
+ `
+})
+class NestedBadge {
+}
diff --git a/src/lib/badge/badge.ts b/src/lib/badge/badge.ts
index 6a396ccf344f..42aca1cfa044 100644
--- a/src/lib/badge/badge.ts
+++ b/src/lib/badge/badge.ts
@@ -177,9 +177,12 @@ export class MatBadge extends _MatBadgeMixinBase implements OnDestroy, CanDisabl
const rootNode = this._renderer || this._document;
const badgeElement = rootNode.createElement('span');
const activeClass = 'mat-badge-active';
+ const contentClass = 'mat-badge-content';
+ // Clear any existing badges which may have persisted from a server-side render.
+ this._clearExistingBadges(contentClass);
badgeElement.setAttribute('id', `mat-badge-content-${this._id}`);
- badgeElement.classList.add('mat-badge-content');
+ badgeElement.classList.add(contentClass);
badgeElement.textContent = this.content;
if (this._animationMode === 'NoopAnimations') {
@@ -232,4 +235,18 @@ export class MatBadge extends _MatBadgeMixinBase implements OnDestroy, CanDisabl
}
}
+ /** Clears any existing badges that might be left over from server-side rendering. */
+ private _clearExistingBadges(cssClass: string) {
+ const element = this._elementRef.nativeElement;
+ let childCount = element.children.length;
+
+ // Use a reverse while, because we'll be removing elements from the list as we're iterating.
+ while (childCount--) {
+ const currentChild = element.children[childCount];
+
+ if (currentChild.classList.contains(cssClass)) {
+ element.removeChild(currentChild);
+ }
+ }
+ }
}