I'm getting a weird bug in my program that is making the *ngIf stop working.
My method:
stripeSubmit(){
this.stripeCheckout = false; // removes the form
this.isLoading = true; // shows a loading spinner
...
this.api.chargeCard(charge).subscribe(res =>{
if(res === "Success"){
this.api.submitOrder(this.orderObj).subscribe(res =>{
this.isLoading = false; // not working
sessionStorage.clear();
this.router.navigate(['/thank-you']) // is working but still displays /cart on top
});
}else {
console.log("ELSE condition"); // works
alert(res); // works
this.stripeFailBoolean = true; // doesn't work
this.stripeCheckout = true; // doesn't work
this.isLoading = false; // doesn't work
console.log(this.isLoading); // logs "false"
}
})
}
});
}
HTML:
...
<h1 class="title">Your Cart</h1>
<img *ngIf="isLoading"id="loading" src="../../../assets/infinitySpinner.svg" alt="">
...
<div *ngIf="stripeFailBoolean" class="alert alert-danger"> Something went wrong, please try again</div>
<div *ngIf="stripeCheckout" class="stripe">
<form class="form mt-4">
<mat-form-field>
<mat-label>Credit Card</mat-label>
<input type="text" matInput [(ngModel)]="cardNumber" name="cardNumber">
</mat-form-field>
<br>
<mat-form-field>
<mat-label>Expiration Month</mat-label>
<input type="number" matInput [(ngModel)]="expMonth" name="expMonth">
</mat-form-field>
<br>
<mat-form-field>
<mat-label>Expiration Year</mat-label>
<input type="number" matInput [(ngModel)]="expYear" name="expYear">
</mat-form-field>
<br>
<mat-form-field>
<mat-label>CVC</mat-label>
<input type="number" matInput [(ngModel)]="cvc" name="cvc">
</mat-form-field>
<br>
<button class="btn btn-secondary submit" (click)="stripeSubmit()" >Submit</button>
</form>
</div>
As is labeled in the commented-out sections above, when I click submit the form goes away and the spinner starts up. if the method chargeCard is a success, the h1 and the loading spinner will stay and the contents of "/thank-you" display underneath them (the URL shows "/thank-you").
if the method does not pass the if statement the alert and the log work but none of the 3 booleans work and the spinner goes indefinitely.
I tried putting all of my booleans in an ngDoCheck, but that didn't help at all.
Anyone know why my booleans work unless inside this one method? Thanks!
*****EDIT: You can replicate the error for yourself if you would like:
rent a boat on the bottom and then go to cart
for a successful transaction use credit card: 4242 4242 4242 4242 12/2024 123
for insufficient funds use credit card: 4000 0000 0000 9995 12/2024 123
The code is at www.github.com/andrethetallguy/howlingwolfefe
***********EDIT 2
Here is the code on Stackblitz: https://angular-ivy-gyhsya.stackblitz.io
It is the Cart Component that is giving me troubles
Thank you soooo much to @Eatos!! The NgZone was definitely the way to go. Here is the new working method:
stripeSubmit(){
this.stripeCheckout = false;
this.isLoading = true;
this.stripeFailBoolean = false;
(<any>window).Stripe.card.createToken({
number: this.cardNumber,
exp_month: this.expMonth,
exp_year: this.expYear,
cvc: this.cvc
}, (status: number, response: any) => {
this.ngZone.run(() => {
if (status === 200) {
let charge: Charge = {
token: response.id,
price: this.total
}
// this.chargeCard(token);
this.api.chargeCard(charge).pipe(takeUntil(this.unsubscibe), tap(()=>{
console.log('inside of charge card tap');
}), switchMap((res: any)=>{
if(res === "Success"){
return this.api.submitOrder(this.orderObj).pipe(tap(()=>{
this.isLoading = false;
sessionStorage.clear();
this.router.navigate(['/thank-you'])
}))
} else {
return of(res).pipe(tap(()=>{
this.stripeFailText = res;
this.stripeFailBoolean = true;
this.stripeCheckout = true;
this.isLoading = false;
}))
}
})).subscribe();
}else {
console.log(response.error.message);
}
console.log('ngZone leave');
})
});
}
ngOnDestroy(){
this.unsubscibe.next();
this.unsubscibe.complete();
}