From f723b93dcb0207cc6a699d9e2b5fef1c849d8a46 Mon Sep 17 00:00:00 2001 From: Godfrey Chan Date: Thu, 8 Jun 2023 11:21:43 -0700 Subject: [PATCH 1/2] Update helper guides to use regular functions Part of: https://github.com/emberjs/ember.js/issues/20054 https://github.com/emberjs/rfcs/pull/866 --- guides/release/components/helper-functions.md | 78 +++++++++++-------- 1 file changed, 47 insertions(+), 31 deletions(-) diff --git a/guides/release/components/helper-functions.md b/guides/release/components/helper-functions.md index 58d296556b..cf6bea6fd8 100644 --- a/guides/release/components/helper-functions.md +++ b/guides/release/components/helper-functions.md @@ -184,32 +184,12 @@ Next to local helpers, ember provides a way to use global helpers. We define glo -To implement the helper, we write a JavaScript function that takes its arguments as an _array_. This is because helpers can also receive _named_ -arguments, which we'll discuss next. +To implement the helper, we define and export a regular JavaScript function: ```js {data-filename="app/helpers/substring.js"} -import { helper } from '@ember/component/helper'; - -function substring(args) { - let [string, start, end] = args; - return string.substring(start, end); -} - -export default helper(substring); -``` - -We can tighten up the implementation by moving the [destructuring](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) into the function's signature. - -```js {data-filename="app/helpers/substring.js" data-diff="+3,-4,-5"} -import { helper } from '@ember/component/helper'; - -function substring([string, start, end]) { -function substring(args) { - let [string, start, end] = args; +export default function substring(string, start, end) { return string.substring(start, end); } - -export default helper(substring); ``` We can then use this helper in the component's template to get the first letter of the username. @@ -255,36 +235,72 @@ Similar to local helpers, global helpers also can mix positional and named argum ``` +```js {data-filename="app/helpers/substring.js"} +export default function substring(string, { start, end }) { + return string.substring(start || 0, end); +} +``` + +### Classic Helpers + +Sometimes, you may encounter helpers defined using the `helper` function: + ```js {data-filename="app/helpers/substring.js"} import { helper } from '@ember/component/helper'; -function substring([string], { start, end }) { +function substring(positional, { start, end }) { + const string = positional[0]; return string.substring(start || 0, end); } export default helper(substring); ``` +
+
+
+
Zoey says...
+
+ Before Ember 4.5, this was the only way to define helpers. +
+
+ +
+
+ +By wrapping the function using the `helper()` function, Ember will extract the +arguments passed from the template. It'll then call your function with an array +(positional arguments passed in the template) and an object (named arguments +passed in the template). + +This style mostly exists for backwards compatibility reasons, but the other +advantage is that it makes it easier to untangle the positional and named +arguments (e.g. when your helper accept an arbitrary number of positional +arguments and optionally some named arguments). Note that, however, it also +makes it more difficult to reuse the logic of the helper function from regular +JavaScript code outside of templates. On the other hand, if you define your +helpers as plain JavaScript function, as we have been doing until now, you are +able to import and call them from any JavaScript files in your app. + ### Class Helpers -Helpers can also be defined using class syntax. For instance, we could define -the substring helper using classes instead. +Classic helpers can also be defined using class syntax. For instance, we could +define the substring helper using classes instead. -```js {data-filename="app/helpers/substring.js" data-diff="-1,+2,-4,+5,+6,+8"} -import { helper } from '@ember/component/helper'; +```js {data-filename="app/helpers/substring.js"} import Helper from '@ember/component/helper'; -function substring([string], { start, length }) { export default class Substring extends Helper { - compute([string], { start, end }) { + compute(positional, { start, end }) { + const string = params[0]; return string.substring(start || 0, end); } } ``` Class helpers are useful when the helper logic is fairly complicated, requires -fine-grained control of the helper lifecycle, or is _stateful_ (we'll be -discussing state in the next chapter). +fine-grained control of the helper lifecycle, is _stateful_ (we'll be +discussing state in the next chapter), or requiring access to a [service](../../services/). ## Built-in Helpers From 60626b271c8961f0a36adbb3a0c3590bcb32c0ec Mon Sep 17 00:00:00 2001 From: Godfrey Chan Date: Thu, 8 Jun 2023 11:23:28 -0700 Subject: [PATCH 2/2] Update guides/release/components/helper-functions.md --- guides/release/components/helper-functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guides/release/components/helper-functions.md b/guides/release/components/helper-functions.md index cf6bea6fd8..00b4b3aa8a 100644 --- a/guides/release/components/helper-functions.md +++ b/guides/release/components/helper-functions.md @@ -292,7 +292,7 @@ import Helper from '@ember/component/helper'; export default class Substring extends Helper { compute(positional, { start, end }) { - const string = params[0]; + const string = positional[0]; return string.substring(start || 0, end); } }