Search code examples
angularangular-ng-if

Angular bug. ngif not working in one method


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:

www.howlingwolfe.com/rentals

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


Solution

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