Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 07c8c8a

Browse files
committed
fix(ngPluralize): fix wrong text content when count is null/undefined
When `lastCount` was evaluated to an non-numeric value (e.g. "other") and `count` was evaluated to `NaN` (e.g. `null`/`undefined`), the text content would be (wrongly) based on the previous template. This commits makes sure the text content is updated correctly. In order to customize the message shown upon `null`/`undefined` one can specify a `'NaN'` property on the `when` exression object. Closes #10836
1 parent 301e7aa commit 07c8c8a

File tree

2 files changed

+94
-42
lines changed

2 files changed

+94
-42
lines changed

src/ng/directive/ngPluralize.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,13 @@ var ngPluralizeDirective = ['$locale', '$interpolate', '$log', function($locale,
217217

218218
// If both `count` and `lastCount` are NaN, we don't need to re-register a watch.
219219
// In JS `NaN !== NaN`, so we have to exlicitly check.
220-
if ((count !== lastCount) && !(countIsNaN && isNaN(lastCount))) {
220+
if ((count !== lastCount) && !(countIsNaN && isNumber(lastCount) && isNaN(lastCount))) {
221221
watchRemover();
222222
var whenExpFn = whensExpFns[count];
223223
if (isUndefined(whenExpFn)) {
224-
$log.debug("ngPluralize: no rule defined for '" + count + "' in " + whenExp);
224+
if (newVal != null) {
225+
$log.debug("ngPluralize: no rule defined for '" + count + "' in " + whenExp);
226+
}
225227
watchRemover = noop;
226228
updateElementText();
227229
} else {

test/ng/directive/ngPluralizeSpec.js

+90-40
Original file line numberDiff line numberDiff line change
@@ -83,52 +83,64 @@ describe('ngPluralize', function() {
8383
}));
8484

8585

86-
it('should show single/plural strings with mal-formed inputs', inject(function($rootScope) {
87-
$rootScope.email = '';
88-
$rootScope.$digest();
89-
expect(element.text()).toBe('');
90-
expect(elementAlt.text()).toBe('');
91-
92-
$rootScope.email = null;
93-
$rootScope.$digest();
94-
expect(element.text()).toBe('');
95-
expect(elementAlt.text()).toBe('');
86+
it('should show single/plural strings with mal-formed inputs', inject(
87+
function($log, $rootScope) {
88+
$rootScope.email = '';
89+
$rootScope.$digest();
90+
expect(element.text()).toBe('');
91+
expect(elementAlt.text()).toBe('');
92+
expect($log.debug.logs.shift()).toEqual([
93+
"ngPluralize: no rule defined for 'NaN' in {" +
94+
"'-1': 'You have negative email. Whohoo!'," +
95+
"'0': 'You have no new email'," +
96+
"'one': 'You have one new email'," +
97+
"'other': 'You have {} new emails'}"
98+
]);
99+
expect($log.debug.logs.shift()).toEqual([
100+
"ngPluralize: no rule defined for 'NaN' in undefined"
101+
]);
102+
103+
$rootScope.email = null;
104+
$rootScope.$digest();
105+
expect(element.text()).toBe('');
106+
expect(elementAlt.text()).toBe('');
96107

97-
$rootScope.email = undefined;
98-
$rootScope.$digest();
99-
expect(element.text()).toBe('');
100-
expect(elementAlt.text()).toBe('');
108+
$rootScope.email = undefined;
109+
$rootScope.$digest();
110+
expect(element.text()).toBe('');
111+
expect(elementAlt.text()).toBe('');
101112

102-
$rootScope.email = 'a3';
103-
$rootScope.$digest();
104-
expect(element.text()).toBe('');
105-
expect(elementAlt.text()).toBe('');
113+
$rootScope.email = 'a3';
114+
$rootScope.$digest();
115+
expect(element.text()).toBe('');
116+
expect(elementAlt.text()).toBe('');
106117

107-
$rootScope.email = '011';
108-
$rootScope.$digest();
109-
expect(element.text()).toBe('You have 11 new emails');
110-
expect(elementAlt.text()).toBe('You have 11 new emails');
118+
$rootScope.email = '011';
119+
$rootScope.$digest();
120+
expect(element.text()).toBe('You have 11 new emails');
121+
expect(elementAlt.text()).toBe('You have 11 new emails');
111122

112-
$rootScope.email = '-011';
113-
$rootScope.$digest();
114-
expect(element.text()).toBe('You have -11 new emails');
115-
expect(elementAlt.text()).toBe('You have -11 new emails');
123+
$rootScope.email = '-011';
124+
$rootScope.$digest();
125+
expect(element.text()).toBe('You have -11 new emails');
126+
expect(elementAlt.text()).toBe('You have -11 new emails');
116127

117-
$rootScope.email = '1fff';
118-
$rootScope.$digest();
119-
expect(element.text()).toBe('You have one new email');
120-
expect(elementAlt.text()).toBe('You have one new email');
128+
$rootScope.email = '1fff';
129+
$rootScope.$digest();
130+
expect(element.text()).toBe('You have one new email');
131+
expect(elementAlt.text()).toBe('You have one new email');
121132

122-
$rootScope.email = '0aa22';
123-
$rootScope.$digest();
124-
expect(element.text()).toBe('You have no new email');
125-
expect(elementAlt.text()).toBe('You have no new email');
133+
$rootScope.email = '0aa22';
134+
$rootScope.$digest();
135+
expect(element.text()).toBe('You have no new email');
136+
expect(elementAlt.text()).toBe('You have no new email');
126137

127-
$rootScope.email = '000001';
128-
$rootScope.$digest();
129-
expect(element.text()).toBe('You have one new email');
130-
expect(elementAlt.text()).toBe('You have one new email');
131-
}));
138+
$rootScope.email = '000001';
139+
$rootScope.$digest();
140+
expect(element.text()).toBe('You have one new email');
141+
expect(elementAlt.text()).toBe('You have one new email');
142+
}
143+
));
132144
});
133145

134146

@@ -144,6 +156,33 @@ describe('ngPluralize', function() {
144156
$rootScope.$digest();
145157
expect(element.text()).toBe('');
146158
}));
159+
160+
it('should be able to specify a message for null/undefined values', inject(
161+
function($compile, $rootScope) {
162+
element = $compile(
163+
'<ng:pluralize count="email"' +
164+
"when=\"{'NaN': 'Unspecified email count'," +
165+
"'0': ''," +
166+
"'one': 'Some text'," +
167+
"'other': 'Some text'}\">" +
168+
'</ng:pluralize>')($rootScope);
169+
170+
$rootScope.email = '0';
171+
$rootScope.$digest();
172+
expect(element.text()).toBe('');
173+
174+
$rootScope.email = undefined;
175+
$rootScope.$digest();
176+
expect(element.text()).toBe('Unspecified email count');
177+
178+
$rootScope.email = '1';
179+
$rootScope.$digest();
180+
expect(element.text()).toBe('Some text');
181+
182+
$rootScope.email = null;
183+
$rootScope.$digest();
184+
expect(element.text()).toBe('Unspecified email count');
185+
}));
147186
});
148187

149188
describe('undefined rule cases', function() {
@@ -195,6 +234,10 @@ describe('ngPluralize', function() {
195234
$rootScope.email = '1';
196235
$rootScope.$digest();
197236
expect(element.text()).toBe('Some text');
237+
238+
$rootScope.email = null;
239+
$rootScope.$digest();
240+
expect(element.text()).toBe('');
198241
}));
199242
});
200243

@@ -243,6 +286,11 @@ describe('ngPluralize', function() {
243286
$rootScope.$digest();
244287
expect(element.text()).toBe('Igor, Misko and 2 other people are viewing.');
245288
expect(elementAlt.text()).toBe('Igor, Misko and 2 other people are viewing.');
289+
290+
$rootScope.viewCount = null;
291+
$rootScope.$digest();
292+
expect(element.text()).toBe('');
293+
expect(elementAlt.text()).toBe('');
246294
}));
247295
});
248296

@@ -296,7 +344,6 @@ describe('ngPluralize', function() {
296344

297345

298346
describe('bind-once', function() {
299-
300347
it('should support for `count` to be a one-time expression',
301348
inject(function($compile, $rootScope) {
302349
element = $compile(
@@ -317,6 +364,9 @@ describe('ngPluralize', function() {
317364

318365
$rootScope.email = 3;
319366
$rootScope.$digest();
367+
368+
$rootScope.email = null;
369+
$rootScope.$digest();
320370
expect(element.text()).toBe('You have 3 new emails');
321371
expect(elementAlt.text()).toBe('You have 3 new emails');
322372

0 commit comments

Comments
 (0)