Score:1

Somehow subscribe/react to addMessage

cn flag

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?

Jaypan avatar
de flag
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?
hga77 avatar
cn flag
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.
Jaypan avatar
de flag
What is the use case?
hga77 avatar
cn flag
@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.
Jaypan avatar
de flag
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.
hga77 avatar
cn flag
@Jaypen, Thanks for your reply. I solved this issue and will add the answer shortly. I'm in the process of contributing the module, Here is the project page https://www.drupal.org/project/shoelace_messages
Score:0
cn flag

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

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.