lanetrotro lanetrotro - 8 days ago 4
TypeScript Question

stripe angular Error: Uncaught (in promise): TypeError: Cannot read property 'stripeService' of undefined

I'm currently trying to implement stripe to my angular4 nodejs application, but I kinda got stuck when i'm trying to send the card token to my server through my service handling the requests relateted to stripe. This is the code I got:

stripe.component.html :

<form role="form" id="payment-form">
<div id="card-element"></div>
<div id="card-errors" role="alert"></div>
<button type="submit" (click)="addCard()">Submit Payment</button>
</form>


stripe.component.ts:

import {Component, OnInit} from "@angular/core";
import {WindowRef} from "../social/windowRef";
import {StripeService} from "./stripe.service";

@Component({
selector: "app-stripe",
templateUrl: './stripe.component.html',
styleUrls: ['./stripe.component.css']
})
export class StripeComponent implements OnInit {
elements: any;
stripe: any;
style: any;
card: any;

constructor(private stripeService: StripeService){}


ngOnInit() {
this.initCardElement();
}

initCardElement(){
this.stripe = WindowRef.get().Stripe("my-key");
this.elements = this.stripe.elements();
this.style =
{
base: {
color: '#32325d',
lineHeight: '24px',
fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
fontSmoothing: 'antialiased',
fontSize: '16px',
'::placeholder': {
color: '#aab7c4'
}
},
invalid: {
color: '#fa755a',
iconColor: '#fa755a'
}
};
this.card = this.elements.create('card', {style: this.style});
this.card.mount('#card-element');
}


addCard() {
this.stripe.createToken(this.card)
.then(function (result) {
if (result.error) {
var errorElement = document.getElementById('card-errors');
errorElement.textContent = result.error.message;
} else {
console.log(result.token);
this.stripeService.addCard(result.token)
.subscribe((response: Response) => {
console.log(response);
}
);
}
});
}
}


I manage to get the stripe's card token but when i'm trying to call my stripeService I got this error:

Error: Uncaught (in promise): TypeError: Cannot read property 'stripeService' of undefined


i understand that
this.stripeService
is not defined here but I don't understand how I can solve this issue.

have a good day :)

rsp rsp
Answer

Use arrow functions if you want to use the outer this. The functions declared with function create a new this which is undefined here.

Run this example to see what's going on:

class X {
  constructor(x) {
    this.x = x;
  }
  a() {
    (function () {
      console.log(this.x);
    })();
  }
  b() {
    (() => {
      console.log(this.x);
    })();
  }
}

let x = new X(10);
x.b();
x.a();

Here the function inside the b() method correctly uses the outer this but the a() method has a function that creates its own this which is undefined and results in the error:

TypeError: Cannot read property 'x' of undefined

In your example you can change this:

addCard() {
    this.stripe.createToken(this.card)
        .then(function (result) {
            if (result.error) {
                var errorElement = document.getElementById('card-errors');
                errorElement.textContent = result.error.message;
            } else {
                console.log(result.token);
                this.stripeService.addCard(result.token)
                    .subscribe((response: Response) => {
                            console.log(response);
                        }
                    );
            }
        });
}

to this:

addCard() {
    this.stripe.createToken(this.card)
        .then((result) => {
            if (result.error) {
                var errorElement = document.getElementById('card-errors');
                errorElement.textContent = result.error.message;
            } else {
                console.log(result.token);
                this.stripeService.addCard(result.token)
                    .subscribe((response: Response) => {
                            console.log(response);
                        }
                    );
            }
        });
}

(not tested)