条带角度错误:未捕获(在承诺中):TypeError:无法读取未定义的属性'stripeService'

时间:2017-07-17 15:00:42

标签: node.js angular typescript promise stripe-payments

我正在尝试将条带实现到我的angular4 nodejs应用程序,但当我尝试通过我的服务处理与条带相关的请求将卡令牌发送到我的服务器时,我有点卡住了。这是我得到的代码:

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);
                            }
                        );
                }
            });
    }
}

我设法得到条纹的卡片令牌,但是当我试图调用我的stripeService时,我收到了这个错误:

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

我知道此处未定义this.stripeService,但我不明白如何解决此问题。

度过美好的一天:)

2 个答案:

答案 0 :(得分:1)

如果要使用外部this,请使用箭头功能。使用function声明的函数会创建一个新的this,此处未定义。

运行此示例以查看发生了什么:

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();

此处b()方法中的函数正确使用外部this,但a()方法有一个函数创建自己的this未定义并导致错误:

TypeError: Cannot read property 'x' of undefined

在您的示例中,您可以更改此内容:

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);
                        }
                    );
            }
        });
}

到此:

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);
                        }
                    );
            }
        });
}

(未经测试)

答案 1 :(得分:0)

当您使用function关键字定义一个匿名或命名的函数时,它会创建一个新范围,this关键字指向新创建的函数的范围。你想要的是引用addCard函数的范围

有几种方法可以做到这一点:

首先,最好的方法是使用不创建新范围的ES6箭头功能 例如:

this.stripe.createToken(this.card)
.then((result) => { 
    console.log(this.stripeService); // it will be defined here
})

第二个选项是存储对addCard范围的引用:

let that = this;
this.stripe.createToken(this.card)
.then((result) => { 
    console.log(that.stripeService); // it will be defined here
})