Angular+Stripe+Firebase项目中processPaymentFS调用未定义报错排查
解决TypeError: Cannot read property 'processPaymentFS' of undefined的问题
兄弟,你遇到的这个错误根源很明确——Stripe Checkout回调函数里的this指向不对!
在你写的closed: function() {...}这个普通函数里,this的上下文是回调函数本身,而不是你的SomeAppComponent组件实例。所以当你试图访问this.paymentSvc时,自然会得到undefined,因为回调函数里根本没有这个属性。
下面给你三种靠谱的解决方案,任选其一就行:
方案1:用箭头函数替代普通函数(最推荐)
箭头函数会自动继承外部上下文的this,也就是你的组件实例,完美解决问题:
ngOnInit() { this.authService.getCurrentUser().subscribe(user => { this.currentUser = user; this.key = this.currentUser.$key; }) this.handler = StripeCheckout.configure({ opened: () => { console.log('payment form opened'); }, // 把普通function改成箭头函数 closed: () => { console.log('payment form closed'); const dataObj = { quantity: this.quantity, amount: this.totalAmount * 100, date: Date.now(), status: 'active' }; console.log("data obj ok"); // 现在this指向组件实例,paymentSvc就能正常访问了 this.paymentSvc.processPaymentFS(this.key, dataObj); console.log('payment successful'); } }); }
方案2:提前保存组件实例的this
在ngOnInit开头把组件的this存到一个变量里,比如self,然后在回调里用self代替this:
ngOnInit() { // 先把组件的this存起来 const self = this; this.authService.getCurrentUser().subscribe(user => { self.currentUser = user; self.key = self.currentUser.$key; }) this.handler = StripeCheckout.configure({ opened: function() { console.log('payment form opened'); }, closed: function() { console.log('payment form closed'); const dataObj = { quantity: self.quantity, amount: self.totalAmount * 100, date: Date.now(), status: 'active' }; console.log("data obj ok"); // 用self访问组件的paymentSvc和key self.paymentSvc.processPaymentFS(self.key, dataObj); console.log('payment successful'); } }); }
方案3:用bind绑定this上下文
把回调函数的this手动绑定到组件实例:
ngOnInit() { this.authService.getCurrentUser().subscribe(user => { this.currentUser = user; this.key = this.currentUser.$key; }) this.handler = StripeCheckout.configure({ opened: function() { console.log('payment form opened'); }, // 用bind把this绑定到组件实例 closed: function() { console.log('payment form closed'); const dataObj = { quantity: this.quantity, amount: this.totalAmount * 100, date: Date.now(), status: 'active' }; console.log("data obj ok"); this.paymentSvc.processPaymentFS(this.key, dataObj); console.log('payment successful'); }.bind(this) // 关键在这里 }); }
额外提醒:注意异步数据的问题
还有个潜在坑:this.authService.getCurrentUser()是异步的,如果你在回调还没返回用户数据的时候就打开并关闭Stripe表单,this.key可能还是undefined。最好把Stripe handler的初始化放到订阅回调里,确保this.key已经赋值:
ngOnInit() { this.authService.getCurrentUser().subscribe(user => { this.currentUser = user; this.key = this.currentUser.$key; // 等用户数据拿到后再初始化handler this.handler = StripeCheckout.configure({ opened: () => { console.log('payment form opened'); }, closed: () => { console.log('payment form closed'); const dataObj = { quantity: this.quantity, amount: this.totalAmount * 100, date: Date.now(), status: 'active' }; console.log("data obj ok"); this.paymentSvc.processPaymentFS(this.key, dataObj); console.log('payment successful'); } }); }) }
这样就能彻底解决问题啦!
内容的提问来源于stack exchange,提问作者ziggy
相关产品推荐
相关产品推荐

