简体   繁体   中英

How to restore default event listener to form submit

I have an order form where the user can change their card information in place before submitting the form.

If they want to use a new card, they can click a button to mount the stripe payment element to the form and they can enter their new card information.

The form submit has an async event.preventDefault(); in order to get the token from stripe so it can be generated and appended to hidden fields before the form is submitted so the token can be used with the stripe gem to charge the user in the controller.

  changeCardButton.addEventListener('click', e => {
    e.preventDefault();
    mountCardField();
  });

  function mountCardField() {
  form.addEventListener('submit', async event => {
    event.preventDefault();
    const { token, error } = await stripe.createToken(card);
    if (error) {
    } else {
      stripeTokenHandler(token);
      form.submit();
    }
  });
}

In the event that the user changes their minds and wants to go back to the saved card information, they can click a back button before submitting the order form:

  cardContainerBackButton.addEventListener('click', e => {
    e.preventDefault();
    unmountCardFieldAndShowLastUsedCard();
  });

  function unmountCardFieldAndShowLastUsedCard() {
    card.unmount();
    form.removeEventListener('submit', event, false);
    changeCardContainer.style.display = 'none';
    cardInfo.style.display = 'block';
  }

However, the form.removeEventListener('submit', event); Doesn't work to restore the forms default behavior and submit as it would by without generating a stripe token.

Uncaught (in promise) IntegrationError: We could not retrieve data from the specified Element.
              Please make sure the Element you are attempting to use is still mounted.

How can I remove the async event submit listener from the form and restore the forms default submit behavior?

I think the issue is in your removeEventListener call. The second argument needs to be the original listener you want to remove, and at the moment you are passing event which appears to be undefined.

To fix it, define the listener as its own function, and use it in both the add and remove :

const listener = async event => {
  event.preventDefault();
  const { token, error } = await stripe.createToken(card);
  if (error) {
  } else {
    stripeTokenHandler(token);
    form.submit();
  }
}

function mountCardField() {
  form.addEventListener('submit', listener);
}

function unmountCardFieldAndShowLastUsedCard() {
  // ...
  form.removeEventListener('submit', listener);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM