in my Angular 5 project I have some problems with the callback from an external library. I load it using
<script src="https://js.chargebee.com/v2/chargebee.js" data-cb-site="my-site"> </script>
and then in Angular I import it as follows:
declare var Chargebee: any;
Chargebee.init({site: "my-site"});
I also have a public variable in my component, lets say publicVar, which I am displaying in the template.
publicVar: string = 'before checkout';
I have the following method:
subscribeToPlan() {
var _self = this;
var chargebeeInstance = Chargebee.getInstance();
chargebeeInstance.openCheckout({
hostedPage: function() {
_self.publicVar = 'hosted-page';
console.log('hosted-page');
},
success: function(hostedPageId) {
_self.publicVar = 'success';
console.log('success');
},
close: function() {
_self.publicVar = 'closed';
console.log('closed');
}
});
}
What is happening when I run the code?
All the console.log functions output the correct data, so I know the chargebee callbacks are called. However, only hostedPage: function() {} correctly changes my publicVar, and it says "hosted-page" in my template.
success: function(){} nor close: function(){} won't update the publicVar in my template. I suspect because these are, unlike the hostedPage, a callback methods and the self. in them has wrong context?
So I worked it out (or found a workaround)
As the _self did hold the correct data, I thought that the change detection is not triggered for those callbacks. After I've manually triggered it, it all works as expected.
Final code and changes:
Import
import { ChangeDetectorRef } from '@angular/core';
Add it to the constructor:
constructor(private cd: ChangeDetectorRef)
And then call it at the end of the callback method, this will manually trigger Angular change detection, and updates template rendering of publicVar
subscribeToPlan() {
var _self = this;
var chargebeeInstance = Chargebee.getInstance();
chargebeeInstance.openCheckout({
hostedPage: function() {
_self.publicVar = 'hosted-page'; // This is not a callback, so it just works
console.log('hosted-page');
},
success: function(hostedPageId) {
console.log('success');
_self.publicVar = 'success';
_self.cd.detectChanges(); // Manual change detection
},
close: function() {
console.log('closed');
_self.publicVar = 'closed';
_self.cd.detectChanges(); // Manual change detection
}
});
}
Alternative code using the arrow functions, as per Joe's suggestion (https://stackoverflow.com/a/50335020/5644425)
subscribeToPlan() {
var chargebeeInstance = Chargebee.getInstance();
chargebeeInstance.openCheckout({
hostedPage: () => {
this.publicVar = 'hosted-page';
console.log('hosted-page');
},
success: hostedPageId => {
console.log('success');
this.publicVar = 'success';
this.cd.detectChanges();
},
close: () => {
console.log('closed');
this.publicVar = 'closed';
this.cd.detectChanges();
}
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With