Why doesn't my code for passing a PHP variable to JavaScript work? I am using the following code, but the JavaScript console prints undefined instead of the value of settings.api_key. What is wrong in the code I am using?

libraries.yml file

stripe_files:
  version: 1.x    
  js:
    https://js.stripe.com/v2/: { type: external, minified: false }
    js/custom_stripe.js: {}
  dependencies:
    - core/jquery
    - core/drupal.ajax
    - core/drupal
    - core/drupalSettings
    - core/jquery.once
  css:
    theme:
      css/custom_stripe_integration.module.css: {}


JavaScript file

(function ($) {
    Drupal.behaviors.stripe = {
      attach: function (context, settings) {
        alert('hello4');
         console.log(settings.api_key);
      }
    };
})(jQuery);


Form class

/**
 * @file
 * Contains \Drupal\amazing_forms\Form\ContributeForm.
 */

namespace Drupal\custom_stripe_integration\Form;
use Drupal\Core;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\user\SharedTempStore;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Locale;

require_once 'modules/custom/donate_gateway/vendor/autoload.php';

/**
 * Contribute form.
 */
class StripeSponsorForm extends FormBase {
  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'stripe_sponsor_form';
  }


  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state,$nid = 0) {
    $config = $this-&gt;config('custom_stripe_integration.settings');
    $api_key = $config-&gt;get('stripe_api_key');

    $form['#attached']['library'][] = 'custom_stripe_integration/stripe_files';
    $form['#attached']['drupalSettings']['api_key'] = $api_key;

    return $form;
  }
}
For anyone coming here looking for a simple example of stashing data in drupalSettings and pulling it back out on the js side. Here's an example in a form.

In  buildForm or form_hook_alter etc:

$form['#attached']['drupalSettings']['foo'] = 'bar';


Then in the js file of your choice (in your theme) be sure to wrap your code in a function and provide the things you want. In this example, I'm providing jQuery and drupalSettings.

(function($, drupalSettings) {

  console.log(drupalSettings);

})(jQuery, drupalSettings);


You should see in your console that the drupalSettings object has the key 'foo' on it alongside some other internal ones. That's why Kevin suggests putting your data a level deeper with ['drupalSettings']['my_module']['foo'], but it's not necessary. Additionally, you don't need to specify core/drupalSettings as a dependency in your libraries.yml or do anything else to make drupalSettings available. You get it for free.



As for actually answering the question . . . I'm not sure what @kiamlaluno is talking about when he says to replace drupalSettings with settings. I can, however, show you (@harshal) what your function should look like based on my example:

(function ($, drupalSettings) {
    Drupal.behaviors.stripe = {
      attach: function (context) {
        alert('hello4');
        console.log(drupalSettings.api_key);
      }
    };
})(jQuery, drupalSettings);


If you're still having trouble, try just adding a couple of lines to be sure things are sane:

(function ($, drupalSettings) {

    // What's going on?
    console.log('function is loading!');
    console.log(drupalSettings);

    Drupal.behaviors.stripe = {
      attach: function (context) {
        alert('hello4');
        console.log(drupalSettings.api_key);
      }
    };
})(jQuery, drupalSettings);