1

I'm trying to find an event that I can subscribe to for the method addMessage.

I need to trigger some code everytime a status message is added. On reacting to this event, I need to send a variable from php to JS. I could not find an event to subscribe to so instead I used a preprocess, below.

<?php
function mymodule_preprocess_status_messages(&$variables) {
  $variables['#attached']['drupalSettings']['send_me_to_js']['_variable'] = 'Going to js...';
}

This preprocess runs everytime addMessage is used and a status message is displayed, but, the variable that i need sent to JS, is not always sent.

For example, this works for messages created from core, and I get the variable in JS. But when Drupal Commerce uses addMessage (eg. when adding a product to cart in ajax setup), the preprocess runs, the status message displays, but the variable is not available in JS.

Here's the javascript:

(function ($, Drupal, drupalSettings) {

  Drupal.behaviors.alwave_alerts = {
    attach: function (context, settings) {
      
      $('.my-class', context).once('unique-string').each(function () { 
        
        // Run after each ajax call
        $(document).ajaxComplete(function () {
          
          // This is sometimes undefined even though the preprocess above runs
          // and there is a status message on screen
          // (eg. when  commerce creates a status message)
          console.log(settings.send_me_to_js);

        });
          
      });
  
    }
  };
  
}(jQuery, Drupal, drupalSettings));

There must be an easy way?

Update:

I discovered that the preprocess does not send the variable to javascript only on ajax requests. On first page load it is sent, but subsequent ajax requests do not send this variable to JS. Seems to be the order sequence in which things are executed during ajax requests.

So the question is, How do I send a variable to JS from this preprocess on ajax calls?

6
  • You didn't actually tell us what you are trying to do, only how you are trying to do it. What is your overall goal here?
    – Jaypan
    Jun 22, 2021 at 1:27
  • The variable is not available in JS on ajax calls. How can I make a variable from this preprocess available in JS during ajax calls? In other words, When a status message is created during an ajax call, this "mymodule_preprocess_status_messages" function will run, and within it is a variable that I need available in JS, $variables['message_list']. How do I make this variable available in JS from an ajax request (not htmlrequest, or initial page load)? The variable is passed during htmlrequest but not subsequent ajax calls. It is undefined in ajax requests within the JS.
    – hga77
    Jun 22, 2021 at 8:36
  • What is the use case?
    – Jaypan
    Jun 22, 2021 at 9:27
  • @Jaypan, I need the variable $variables['message_list'] in JS so I can replace the status masseges and create them as floating popups, using a 3rd party javascript library. No need for the status_masseges template either since the markup comes from the library. This library needs to get the messages data to create the messages hence the reason I need to give it this variable.
    – hga77
    Jun 22, 2021 at 11:53
  • I've set up floating status messages in the past by altering the template to match the output, then creating a JS file that calls the JS to make the message a popup using Drupal.behaviors. But it seems you're set on doing it the way you're trying, unfortunately I don't have the answer to the method you are trying to do it, I only know how I didi it.
    – Jaypan
    Jun 22, 2021 at 18:02

1 Answer 1

0

I managed to resolve this issue. Basically, the problem was that I could not pass a variable from the preprocess function to JavaScript during AJAX requests (as mentioned several times in this issue). So what I did:

  1. Inside the preprocess, I set a private temp store variable for later use during AJAX requests.
  2. A custom AJAX Callback Command was created that accepts the variable and invokes a JavaScript function, which in turn receives the variable.
  3. I then subscribe to a response event that runs on every request. The event is KernelEvents::RESPONSE.
  4. Inside the handler for this event, I check that we are in an AJAX request, then retrieve the variable from the temp store, that was previously set.
  5. I use the custom AJAX Command, giving it the tempstore variable, which sends it to JavaScript. Done!

You can find the complete code in this module: https://www.drupal.org/project/shoelace_messages

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.