I’m doing a quick prototype of Stripe elements (https://stripe.com/docs/js).
It seems to load and run just fine and I can create payment tokens, but it breaks Vaadin in the process. Run the code below and when you open the page in Safari and click the Select component I get the error:
TypeError: undefined is not an object (evaluating 'this._items[this._menuElement.selected]
')
The same page in Chrome and Firefox does not produce the TypeError. Vaadin is 14.4.2.
Any suggestions to what might cause this? Initially I thought it was an issue with Stripe.js, but after realizing that the TypeError doesn’t occur in Chrome or Firefox, nor does it happen if I mount stripe.js manually (see below), I wonder if this is something else or an issue in Vaadin.
@Route(value = "stripe-connect")
@JavaScript("https://js.stripe.com/v3/")
public class StripeConnect extends Composite<Div> {
public StripeConnect() {
// Add select component. The select "breaks" when Stripe.js is mounted.
Select<String> select = new Select<>("Select Something");
select.setItems("Item A", "Item B", "Item C");
getContent().add(select);
// Instructions
Div instructions = new Div(new Span("Hint: use 4111 1111 1111 1111 as the card number."));
getContent().add(instructions);
// Add element to contain the stripe elements fields
Div cardElement = new Div();
cardElement.setId("cardelement");
cardElement.setMaxWidth("600px");
getContent().add(cardElement);
// initialize stripe.js and mount to card element
String js = "var style = {\n" + " base: {\n" + " color: '#32325d',\n"
+ " fontFamily: '\"Helvetica Neue\", Helvetica, sans-serif',\n"
+ " fontSmoothing: 'antialiased',\n" + " fontSize: '16px',\n" + " '::placeholder': {\n"
+ " color: '#aab7c4'\n" + " }\n" + " },\n" + " invalid: {\n" + " color: '#fa755a',\n"
+ " iconColor: '#fa755a'\n" + " }\n" + "};\n" + ""
+ "$0.stripe = Stripe('pk_test_1DU6AgiPLPgyzdgvhHy3jTVb');\n" + "var elements = $0.stripe.elements();"
+ "$0.card = elements.create('card', {style: style});\n"
+ "var cardElement = document.getElementById('cardelement');\n" + "$0.card.mount(cardElement);\n";
UI.getCurrent().getPage().executeJs(js, this.getElement());
// Create payment token based on user input
Button btnSubmit = new Button("Submit", e -> {
UI.getCurrent().getPage().executeJs("console.log('card=' + $0.card);", this.getElement());
String submitJs = " $0.stripe.createToken($0.card).then(function(result) {\n" + " if (result.error) {\n"
+ " alert('ERROR: ' + result.error.message);\n" + " } else {\n"
+ " alert('OK token='+ result.token.id);\n" + " }\n" + " });\n";
UI.getCurrent().getPage().executeJs(submitJs, this.getElement());
});
getContent().add(btnSubmit);
}
}
The TypeError does not happen if Stripe elements is mounted later (e.g. by clicking a button).
getContent().add(new Button("Mount Stripe Elements", e -> {
UI.getCurrent().getPage().executeJs(js, this.getElement());
}));