3.3 KiB
3.3 KiB
title, impact, impactDescription, tags
| title | impact | impactDescription | tags |
|---|---|---|---|
| No helper() Wrapper for Plain Functions | LOW-MEDIUM | Simpler code, better performance | helpers, templates, modern-ember |
No helper() Wrapper for Plain Functions
In modern Ember, plain functions can be used directly as helpers without wrapping them with helper(). The helper() wrapper is legacy and adds unnecessary complexity.
Incorrect (using helper() wrapper):
// app/utils/format-date.js
import { helper } from '@ember/component/helper';
function formatDate([date]) {
return new Date(date).toLocaleDateString();
}
export default helper(formatDate);
Correct (plain function):
// app/utils/format-date.js
export function formatDate(date) {
return new Date(date).toLocaleDateString();
}
Usage in templates:
// app/components/post-card.gjs
import { formatDate } from '../utils/format-date';
<template>
<article>
<h2>{{@post.title}}</h2>
<time>{{formatDate @post.publishedAt}}</time>
</article>
</template>
With Multiple Arguments:
// app/utils/format-currency.js
export function formatCurrency(amount, currency = 'USD') {
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency,
}).format(amount);
}
// app/components/price.gjs
import { formatCurrency } from '../utils/format-currency';
<template>
<span class="price">
{{formatCurrency @amount @currency}}
</span>
</template>
For Helpers that Need Services (use class-based):
When you need dependency injection, use a class instead of helper():
// app/utils/format-relative-time.js
export class FormatRelativeTime {
constructor(owner) {
this.intl = owner.lookup('service:intl');
}
compute(date) {
return this.intl.formatRelative(date);
}
}
Why Avoid helper():
- Simpler: Plain functions are easier to understand
- Standard JavaScript: No Ember-specific wrapper needed
- Better Testing: Plain functions are easier to test
- Performance: No wrapper overhead
- Modern Pattern: Aligns with modern Ember conventions
Migration from helper():
// Before
import { helper } from '@ember/component/helper';
function capitalize([text]) {
return text.charAt(0).toUpperCase() + text.slice(1);
}
export default helper(capitalize);
// After
export function capitalize(text) {
return text.charAt(0).toUpperCase() + text.slice(1);
}
Common Helper Patterns:
// app/utils/string-helpers.js
export function capitalize(text) {
return text.charAt(0).toUpperCase() + text.slice(1);
}
export function truncate(text, length = 50) {
if (text.length <= length) return text;
return text.slice(0, length) + '...';
}
export function pluralize(count, singular, plural) {
return count === 1 ? singular : plural;
}
// Usage
import { capitalize, truncate, pluralize } from '../utils/string-helpers';
<template>
<h1>{{capitalize @title}}</h1>
<p>{{truncate @description 100}}</p>
<span>{{@count}} {{pluralize @count "item" "items"}}</span>
</template>
Plain functions are the modern way to create helpers in Ember. Only use classes when you need dependency injection.
Reference: Ember Helpers - Plain Functions