Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Callback revived on incorrect component #38

Open
henninglive opened this issue Sep 16, 2024 · 2 comments
Open

Callback revived on incorrect component #38

henninglive opened this issue Sep 16, 2024 · 2 comments
Labels
bug Something isn't working

Comments

@henninglive
Copy link

henninglive commented Sep 16, 2024

Rapidly creating NgxTurnstileComponents may cause the window callback to be received after components has been destroyed or on a different NgxTurnstileComponent.

Example:

export class NgxTurnstileComponent implements AfterViewInit, OnDestroy {

  ....
  name!: string;

  public ngAfterViewInit(): void {
    console.log('ngAfterViewInit', this.name);
    
    let turnstileOptions: TurnstileOptions = ...

    window[CALLBACK_NAME] = () => {
      if (!this.elementRef?.nativeElement) {
        return;
      }

      console.log('callback', this.name)
      
      this.widgetId = window.turnstile.render(
        this.elementRef.nativeElement,
        turnstileOptions,
      );
    };

    if (this.scriptLoaded()) {
      window[CALLBACK_NAME]();
      return;
    }

    ...
  }
  
  public ngOnDestroy(): void {
    console.log('ngOnDestroy', this.name)
    ...
  }

}
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { NgxTurnstileComponent } from './ngx-turnstile.component';

describe('NgxTurnstileComponent', () => {
  let component: NgxTurnstileComponent;
  let fixture: ComponentFixture<NgxTurnstileComponent>;

  let run = 1;
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [NgxTurnstileComponent],
    }).compileComponents();

    fixture = TestBed.createComponent(NgxTurnstileComponent);
    component = fixture.componentInstance;
    component.siteKey = '1x00000000000000000000AA';
    component.name = 'test-' + run++;
    fixture.detectChanges();
  });

  it(`should create 1`, () => {
    expect(component).toBeTruthy();
  });

  it(`should create 2`, () => {
    expect(component).toBeTruthy();
  });

});
NgxTurnstileComponent
✅should create 1
❌should create 2

LOG: 'ngAfterViewInit', 'test-1'
LOG: 'ngOnDestroy', 'test-1'                                                                                                                                                                                
LOG: 'ngAfterViewInit', 'test-2'                                                                                                                                                                            
LOG: 'callback', 'test-2'
LOG: 'ngOnDestroy', 'test-2'
LOG: 'callback', 'test-2'                                                                                                                                                                                                                                                                                                                                                    

TypeError: Cannot read properties of undefined (reading 'render')
    at window.<computed> (http://localhost:9876/_karma_webpack_/webpack:/src/app/ngx-turnstile/ngx-turnstile.component.ts:110:40)
    at NgxTurnstileComponent.call [as ngAfterViewInit] (http://localhost:9876/_karma_webpack_/webpack:/src/app/ngx-turnstile/ngx-turnstile.component.ts:117:28)
    at callHookInternal (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2022/core.mjs:5153:14)
    at callHook (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2022/core.mjs:5180:13)
    at callHooks (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2022/core.mjs:5134:17)
    at executeInitAndCheckHooks (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2022/core.mjs:5084:9)
    at refreshView (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2022/core.mjs:13858:21)
    at detectChangesInView (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2022/core.mjs:13999:9)
    at detectChangesInViewWhileDirty (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2022/core.mjs:13694:9)
    at detectChangesInternal (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2022/core.mjs:13673:9)
@AleksanderBodurri AleksanderBodurri added the bug Something isn't working label Sep 16, 2024
@choyiny
Copy link
Member

choyiny commented Oct 4, 2024

@henninglive what is the use case of rapidly creating many turnstile widgets at once? Do you have a production use-case where this is important?

@henninglive henninglive changed the title Callback revived on incorrect window Callback revived on incorrect component Oct 8, 2024
@henninglive
Copy link
Author

henninglive commented Oct 8, 2024

@choyiny it's mainly an issue in test code.

We encountered this problem when writing unit tests for Angular components containing a NgxTurnstileComponent. Since jasmine unit tests typical recreate the component between each test case, we would consistently receive callbacks after the NgxTurnstileComponent had been destroyed or on a different NgxTurnstileComponent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Development

No branches or pull requests

3 participants