0

Problem: I'm running into an issue where I am unable to tokenize the credit card information posted inside of the card stripe element I am mounting to my component.

I am currently using the Nebular stepper component (https://akveo.github.io/nebular/docs/components/stepper/overview#nbsteppercomponent) and have a nested child component with the following ts code:

public async fetchCardInput(): Promise<any> {
    let address: Address = this.ccAddress.fetchAddressData();
    let name = this.getCardholderName();
    let line2 = address.getAddressLine2();

    let cardTokenPayload = {
        name: name,
        address_line1: address.getAddressLine1(),
        address_city: address.getCity(),
        address_state: address.getState(),
        address_zip: address.getZipCode(),
        country: this.constants.US,
        currency: this.constants.USD
    };

    if (line2) {
        cardTokenPayload['address_line2'] = line2;
    }

    const { token, error } = await this.stripe.createToken(this.card, cardTokenPayload);

    if (error) {
        console.log('Something went wrong: ', error);
        return null;
    } else {
        console.log('SUCCESS! Token: ', token);

        let data = {
            tokenId: token.id,
            address: address,
            cardholderName: name
        }

        return data;
    }
}

html (pulled out the html and ts from the child component but it's still behaving the same way):

<nb-step label="Payment / Payout">
  <div class="heading">{{ constants.PAYMENT_INFORMATION }}</div>
  <label class="input-label">{{ constants.CREDIT_CARD_INFORMATION }}</label>
  <div class="card-container">
      <div id="card-element" #cardElement></div>
  </div>
  <div *ngIf="error" class="error mt-10">{{ error }}</div>
</nb-step>

The thing is, this implementation works completely fine when it's not nested inside of the Nebular component. Has anyone found a work-around for this issue or at least familiar with Nebular components and what they're doing under the hood?

EDIT: Adding the browser exception:

ERROR Error: 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.

I am using Angular 8 and Nebular 4.5.0.

Thanks in advance!

Scott
  • 697
  • 8
  • 18
  • What exactly is going wrong? Are you getting an error? – Paul Asjes Apr 27 '20 at 02:39
  • Yeah, I am getting an exception in the browser. I updated my post with the error. – Scott Apr 27 '20 at 13:34
  • are you sure you added stripe script to your file? – rijin Apr 27 '20 at 13:44
  • Hmm, does Nebular stepper remove elements from the DOM when a step is not in view? It looks like the Stripe Element is missing from the DOM which causes stripe.js to fail when you try to use it. – Paul Asjes Apr 28 '20 at 01:01
  • @rijin Yes, the stripe api calls work just fine when the form is moved outside of the Nebular Stepper component. The issue occurs when the form is nested inside a child component. – Scott May 02 '20 at 22:03
  • @PaulAsjes that's what I'm guessing. I reached out to their support but haven't gotten an answer yet. I'm guessing the DOM elements are being hidden in the shadow DOM of the component. The weird thing is that when I print out the html element from my typescript file, it knows the element exists before making the call to tokenize the credit card data. – Scott May 02 '20 at 22:05
  • I got a similar issue when integrated stripe card into the Vue component. My solution for Vue was to move card component initialization from "created" to "mounted" lifecycle hook. I do not see where you do your init, but make sure it happens after the component is fully rendered and div#card-element is visible and won't be manipulated until the card token is fetched. – Yura Fedoriv Oct 02 '20 at 08:42

0 Answers0