0

Class Documentation: SettingsCommand

I'm trying to figure out how to use this Ajax Command correctly. I must be confused from the documentation, so I'm hoping someone can shed some light where I'm mistaken.

__construct(array $settings, $merge = FALSE)

array $settings: An array of key/value pairs of JavaScript settings.
bool $merge: Whether the settings should be merged into the global drupalSettings.

Given the array already in drupalSettings: ['drupalSettings']['myData'] = [1,2,3,4,5];
And the following ajaxCallback I would like to replace the 'myData' array with [2, 4]:


    namespace Drupal\settings_controller_test\Form;

    use Drupal\Core\Form\FormBase;
    use Drupal\Core\Form\FormStateInterface;
    use Drupal\Core\Ajax\AjaxResponse;
    use Drupal\Core\Ajax\SettingsCommand;

    class SettingsControllerTestForm extends FormBase
    {
        public function getFormId() { return 'settings_controller_test_form'; }

        public function buildForm(array $form, FormStateInterface $form_state)
        {
            $form['invoker'] = [
                '#type' => 'submit',
                '#value' => t('Invoke Callback'),
                '#ajax' => [
                    'callback' => [$this, 'ajaxCallback']
                    ]
                ];

            $form['#attached']['drupalSettings']['myData'] = [1,2,3,4,5];
            $form['#attached']['library'][] = 'settings_controller_test/test';
            return $form;
        }

        public function ajaxCallback(array &$form, FormStateInterface $form_state)
        {
            $response = new AjaxResponse();

            #clear old myData settings
            $response->addCommand(new SettingsCommand(['myData' => []], TRUE));

            #add new data for myData settings
            $response->addCommand(new SettingsCommand(['myData' => [2,4]], TRUE));

            return $response;
        }

        public function validateForm(array &$form, FormStateInterface $form_state){}
        public function submitForm(array &$form, FormStateInterface $form_state){}
    }

I'm testing the state of 'myData' in JavaScript using the following:


(function ($, Drupal, drupalSettings) {
    Drupal.behaviors.myBehaviour = {
      attach: function (context) {
        //output: [1, 2, 3, 4, 5]
        console.log(drupalSettings.myData);


        $(document).once().ajaxComplete(function(event, xhr, settings) {
          //output: [2, 4, 3, 4, 5]
          console.log(drupalSettings.myData);
        });

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

UPDATE: The attempt to clear the myData array fails. Then when I attempt to set myData = [2,4] with merge set as TRUE the leading two elements change to 2,4 and the remaining elements in the array are still there.
NOTE: If I change: $response->addCommand(new SettingsCommand(['myData' => [2,4]], TRUE)); to $response->addCommand(new SettingsCommand(['myData' => [2,4]], FALSE)); the myData array remains completely unchanged [1,2,3,4,5]

  • Is that the only JS you have to test it? – Kevin Jan 9 at 20:53
  • I've added another JS test case to the question. I added a test button to trigger logging the current settings.myData array to the console. Before and after the ajaxCallback is invoked. The result remains the same. – Devin Jan 9 at 21:28
  • The settings command without merging only makes sense if you use a local drupalSettings, see the discussion here drupal.stackexchange.com/questions/272020/… – 4k4 Jan 9 at 21:45
  • @4k4 To my understanding merging will append the array, I'm wanting to replace the array. I believe I'm using drupalSettings. I'm attaching myData via the following: $form['#attached']['drupalSettings']['myData'] = [1,2,3,4,5] – Devin Jan 9 at 22:01
  • @4k4 If the method I'm attempting to change the ['drupalSettings']['myData'] is incorrect. Could you direct me to a compatible solution to change the settings variable during an ajax callback? – Devin Jan 9 at 22:07
1

Yes you need one more command to set the data back to nothing before you can overide it from trial and error the "merge" FALSE does nothing. so ...

// $response = new AjaxResponse();
// If want to replace you need to empty the array first.
$response->addCommand(new SettingsCommand([
  'MyData' => [],
], TRUE));
// then add new ones.
$response->addCommand(new SettingsCommand([
  'MyData' => [
    'New' => 'New values'
  ],
], TRUE));

See my New full example: https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Ajax%21SettingsCommand.php/class/SettingsCommand/8.6.x#comment-64379

  • Thank you for your examples here and on the API reference page. I've reviewed them and made the necessary changes with still no luck. I've updated the question with the new details. – Devin Jan 10 at 7:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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