Score:0

drupalSettings values lost when accessed from a named function

cl flag

I have a custom module and in it's .module file I add a value to Drupal settings:

  $variables['#attached']['drupalSettings']['my module']['color_body'] = '#dd0000';

I have a named js function and try to access the value:

function loadcal() {
  var backgroundColor = drupalSettings.mymodule.color_body;
}

I receive the error:

Uncaught TypeError: Cannot read properties of undefined (reading 'my module')
at Object.attach (loadcal.js?rb7yo3:52:37)

All of the working examples of using drupalSettings seem to be with anonymous functions:

(function ($) {}

I can refactor to do this as a DOMready function, but would prefer this function to be callable. I have tried:

(function loadcal($) {}

but that leaves loadcal() not being found when it is called.

UPDATE

I decided I could do without the function being named. I could pass what I needed at the start and not have to make subsequent calls. Here is the code involved:

mymodule.libraries

mymodule.calendar:
  css:
    component:
      css/calendar.css: {}
  js:
    js/loadcal.js: { weight: -18 }
  dependencies:
    - core/Drupal
    - core/jQuery
    - core/drupalSettings

mymodule.module

function mymodule_preprocess_node($variables) {
  $config = \Drupal::config('mymodule.settings');
  $variables['#attached']['library'][] = 'mymodule/mymodule.calendar';
  $variables['#attached']['drupalSettings']['mymodule']['color_body'] = '#dd0000';
}

loadcal.js

(function (Drupal, drupalSettings, once) {
  Drupal.behaviors.mymodule = {
    attach: function (context, settings) {
      var calendar = new FullCalendar.Calendar(calendarEl, {
        dayCellDidMount: ({date, el}) => {
          el.style.backgroundColor = drupalSettings.mymodule.color_body;
        }
      }
   }
)}

The console error is:

Uncaught TypeError: Cannot read properties of undefined (reading 'color_body')

though when checking drupalSettings, and settings under Closure (attach), or Closure.drupalSettings, mymodule isn't there, though it shows up under Drupal.behaviors.

cn flag
Why the space in `'my module'`?
apaderno avatar
us flag
The exception message doesn't match the shown code. With `drupalSettings.mymodule`, it should not complain about reading the *my module* property of `undefined`.
apaderno avatar
us flag
You can either use `(function ($) { /* code */ })(jQuery)` or `(function loadcal($) { /* code */ })(jQuery)`. The latter would be helpful if that function calls itself (which doesn't usually happen with Drupal behaviors).
cn flag
This will probably come down to how you're including the JS in the page or how/when you're invoking `loadcal()`
apaderno avatar
us flag
@Clive Yes, that's true. We need to see more code, but so far this seems a plain JavaScript question.
cn flag
`$variables` needs to be `&$variables` in the preprocess function declaration
cl flag
Thank you! I’ll fix that and try as soon as I stop banging my head on the desk :)
cl flag
Yup. Works. Please add it as an answer.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.