ru
How to use @drupal/once in the right way

How to use @drupal/once in the right way

Why do we need @drupal/once

We need the @drupal/once library to ensure that the code runs exactly once. Since Drupal Behaviors are run every time Drupal Ajax is executed, we need to make sure the code runs one time.

Previously this was done by the jQuery.once library, now we have its native alternative @drupal/once that is available in Drupal core since 9.2.

How to use @drupal/once

Add core/once library as a dependency to Drupal library:

my-library:
  dependencies:
    - core/once

To allow global function in eslint, add this to your .eslintrc.json file:

{
  "globals": {
    "once": true
  }
}

Examples of use

Find one element:

const [editorMenu] = once('editor-menu', '.editor-menu', context)
if (editorMenu) {
  console.log(editorMenu)
}

Find several elements:

// Using Array.foreach()
const editorMenuItems = once('editor-menu-items', '.menu-item', context)
editorMenuItems.forEach(item, index) => {
  console.log(item, index)
}

// or using for...of
const editorMenuItems = once('editor-menu-items', '.menu-item', context)
for (item of editorMenuItems) {
  console.log(item)
}

Vscode snippets

For the VSCode editor, we can prepare custom snippets so that we don't have to write once wrapper every time by hand:

{
  "once drupal behavior (one element)": {
    "prefix": "oncedrupal",
    "body": "const [${1:element}] = once('${2:once-string}', '${3:selector}', context);\nif (${1:element}) {\n// code \n}",
    "description": "once drupal behavior (one element)"
  },
  "once drupal behavior (array foreach)": {
    "prefix": "oncedrupal",
    "body": "const ${1:array} = once('${2:once-string}', '${3:selector}', context);\n${1:array}.forEach(${4:element} => {\n// code \n});",
    "description": "once drupal behavior (array foreach)"
  },
  "once drupal behavior (array for of)": {
    "prefix": "oncedrupal",
    "body": "const ${1:array} = once('${2:once-string}', '${3:selector}', context);\nfor (const ${4:element} of ${1:array}) {\n// code \n};",
    "description": "once drupal behavior (array for of)"
  }
}

References:

Last Updated: