I needed a way to display a nicely-readable list of strings for an app I’m working on. And by that, I mean that I wanted to display, "Mary, John, and Mark" instead of "Mary, John, Mark". A simple ngRepeat would have been too complex for this, so, filters to the rescue!
[more]
Let’s back up a step and talk about why… Why the heck would I want to invest energy in changing from this:
"Mary, John, Mark"
to this:
"Mary, John, and Mark"
The difference is subtle, but I think touches like that go a long way towards improving the overall UX of an app, especially when your target users aren’t the technical type to begin with.
A Naive Solution
I started off thinking, "Well, I could just use an ngRepeat or something…", but I quickly abandoned that idea. It would have looked something like this:
<p>
<span ng-repeat="person in people">{{person}}{{$index < (people.length-1) ? ',' : ''}}</span>
</p>
It’s already unreable and I didn’t actually get my ‘and’ in there!
A Better Solution
So, ngRepeat is off the table. Instead, I decided to go with a filter.
(function (undefined) {
angular.module('app').filter('sentenceJoin', () => sentenceJoin);
function sentenceJoin(value, finalSeparator) {
//If we didn't get an array, just return the value.
if (!value || !value.constructor === Array) return value;
//If there's a single item, just return it...
if (value.length === 1) return value[0];
//If there's only two, we don't need a comma...
if (value.length === 2) return `${value[0]} ${finalSeparator} ${value[1]}`;
//Otherwise, join it up, throw the final separator in place at the end!
return `${value.slice(0, value.length - 1).join(', ')}, ${finalSeparator} ${value.slice(-1)}`;
}
})();
Now my solution looks like this:
<p>
{{people | sentenceJoin:'and'}}
</p>
Assuming people=['Mary','John','Mark']
, this gives me <p>Mary, John, and Mark</p>
.
And if I only have two people, people=['Mary','John']
, I get back <p>Mary and John</p>
.
Again, this isn’t a HUGE change from what I could have gotten with just a simple Array.join
call, but it’s the little things that make the difference between a good UX and a great one.