'Grammatically correct plural / singular endings
Using a for loop, I have created a counter for late items by looping through items retrieved in a web request, setting a property of late
as true
if conditions are met, and incrementing the counter.
Using *ngIf
, I could do the following:
<h5 *ngIf="lateCount != 1">You have {{lateCount}} late items.</h5>
<h5 *ngIf="lateCount == 1">You have {{lateCount}} late item.</h5>
Is there a way to do this without two *ngIf
s?
Solution 1:[1]
Well you can trigger only s
symbol on condition:
<h5>You have {{lateCount}} late item<ng-container *ngIf="lateCount == 1">s</ng-container>.</h5>
Another approach would be to write a pipe that does this for you, or furthermore, you can use Angular i18n (any other library) that provides the functionality to work with pluralization.
Solution 2:[2]
I know this question was asked a lot of time ago, but just to complete the argument there's another way you can accomplish the given task and that's by using the ngPlural
directive.
Primarily ngPlural
directive adds/removes DOM elements based on a numeric values
The ngPlural
directive is very handy and can be used with the Common Locale Data Repository (CLDR) defined category matches such as: one, few or many. As from the angular documentation you can use the directive as follows:
<some-element [ngPlural]="value">
<ng-template ngPluralCase="=0">there is nothing</ng-template>
<ng-template ngPluralCase="=1">there is one</ng-template>
<ng-template ngPluralCase="few">there are a few</ng-template>
</some-element>
For more information about the directive please see ngPlural. Hope it helps :)
Solution 3:[3]
I know it's a bit late, but there's a neater way to solve the problem, with pipes.
Here you can learn how to use it, it's really simple and reusable:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'pluralSingular'
})
export class PluralSingularPipe implements PipeTransform {
transform(number: number, singularText: string, pluralText: string = null): string {
let pluralWord = pluralText ? pluralText : `${singularText}s`;
return number > 1 ? `${number} ${pluralWord}` : `${number} ${singularText}`;
}
}
Usage:
{{ someNumberVariable | pluralSingular:'city':'cities }}
Solution 4:[4]
As the answer below says you can use NgPlural
Your template should look like:
<h5 [ngPlural]="lateCount">
You have {{lateCount}} late
<ng-template ngPluralCase="=1">item.</ng-template>
<ng-template ngPluralCase="other">items.</ng-template>
</h5>
Solution 5:[5]
I don't think we should be doing if/else logic on English plural words.
Let's make a smart suffix pipe instead.
- This pipe runs logic on plural words, defaulting to
s
. - Optionally add a replacement plural suffix like
ies
. Then words ending iny
are replaced withies
.
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'plural',
})
export class PluralPipe implements PipeTransform {
transform(word: string, count: number, pluralForm: string = 's'): string {
let transformed;
// 'ies' vs singular 'y' (city / cities)
if (pluralForm === 'ies') {
// replace y with ies
transformed = count != 1 ? word.replace(/.$/, pluralForm) : word;
} else {
// default to plural 's' (applicant / applicants)
transformed = count === 1 ? word : word + pluralForm;
}
// console.log(count, word, transformed);
return transformed;
}
}
Basic usage (s
is default)
{{ 'comment' | plural: 2 }} // comments
Advanced usage (ies
for plural replaces words ending in y
)
{{ 'reply' | plural: 3:'ies' }} // replies
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Swinkaran |
Solution 3 | |
Solution 4 | Alex Z |
Solution 5 |