1

Im trying to send a beacon when a user closes the browser window that they are viewing on my site. I am using Angular 13 and using the window and navigator javascript apis to do it.

First I know call back crazy in my init post. Its going to get fixed just not something I care about right now.

ngOnInit(): void {
    window.scrollTo(0,0);
    this.route.params
      .subscribe(
        (params: Params)=>{
          this.creatorslug = params['creatorslug'];
          this.userobject = this.authservice.getUser$()
            .subscribe(
              (object : any)=>{
                this.userobject = object;
                this.http.get(environment.add_user_to_content_creator_shochat_stream + this.creatorslug)
                  .subscribe(
                    (req: any)=> {
                      this.shochatobject = req;
                      window.addEventListener('beforeunload', ev => {
                        const payload = {
                          shochatid: this.shochatobject['shochatid']
                        };
                        if(!this.properleave){
                          //@ts-ignore
                          navigator.sendBeacon(environment.receive_beacon_user_leave_shochat, payload)
                        }

                        });
                      this.loaded = true;
                      this.syncsubscription = this.tss.receiveSyncClient()
                        .subscribe(
                          (req: any) => {
                            if(req != null){
                              this.syncClient = req;
                              this.syncClient.document(this.tss.setdocumentname(this.shochatobject['contentcreatordisplayname'])).then((doc) => {
                                if(doc.data.killshochat){
                                  this.leaveshochat();
                                }
                              });

                              this.syncClient.document(this.tss.setdocumentname(this.shochatobject['contentcreatordisplayname'])).then((doc)=>{
                                doc.on('updated', (event)=>{
                                  if(event.data.killshochat){
                                    this.leaveshochat();
                                  }
                                });
                              });
                            }

                          });
                    });
              });
        });
  }

Notice on the init function of the component im sharing I define the beforeunload listener

window.addEventListener('beforeunload', ev => {
                            const payload = {
                              shochatid: this.shochatobject['shochatid']
                            };
                            if(!this.properleave){
                              //@ts-ignore
                              navigator.sendBeacon(environment.receive_beacon_user_leave_shochat, payload)

the proper leave boolean is in regards to a flag that gets called if the user leaves the page correctly.

leaveshochat(){
    this.properleave = true;
    // @ts-ignore
    const url = environment.user_leave_shochat + this.shochatobject.shochatid;
    this.http.delete(url)
      .subscribe(
        (req: any)=>{
          // @ts-ignore
          this.router.navigate(['user-services', 'user-shochat-end', this.shochatobject.shochatid]);
        });
  }

but what happens when I test closing the browser window without clicking the button that uses the leaveshochat() function the beacon does not send. I imagine I'm doing something silly.

update I read this article and then tried this but still no change in action

@HostListener('window:beforeunload',['$event'])

  unloadHandler(event: Event){
    const payload = {
      shochatid: this.shochatobject['shochatid']
    };
    if(!this.properleave){
      //@ts-ignore
      navigator.sendBeacon(environment.receive_beacon_user_leave_shochat, payload)
    }
  }
  • Did you open Network tab/browser terminal and mark "persist log" kind of settings in browsers? that should give you some idea on where the problem is? If any issues, they are captured in log, post page refresh and re-loads. I appreciate you using sendBeacon() to capture some critical log data. I've used this modern API heavily on [**timeonsite JS**](https://saleemkce.github.io/timeonsite/docs/index.html#real-time-example) tracker. It seems most reliable, promising and fantastic. – webblover Jun 22 '22 at 07:02

1 Answers1

2

Assuming that this problem doesn't come from mobile device? For example, these events will not fire in the following situation:

  1. The user loads the page and interacts with it.
  2. When they are finished, they switch to a different app, instead of closing the tab.
  3. Later, they close the browser app using the phone's app manager.

The other thing I don't see here is what is this.properleave? Are you sure it is in the correct state when user is leaving? Anyway, I tried to test it and I am able to post message content beforeunload.

  ngOnInit() {
    this.subscribeToNativeNavigation();
  }

  private subscribeToNativeNavigation() {
    fromEvent(window, 'beforeunload')
    .subscribe((e) => {
      const message = 'Sending data';
      (e || window.event).returnValue = !message;
      console.log(message)
      navigator.sendBeacon('/log', message);
      return message;
    })
  }

  refreshPage() {
    location.reload();
  }

Example: https://stackblitz.com/edit/beforeunload-warning-kmbxjl?file=src%2Fapp%2Fapp.component.ts

Joosep Parts
  • 5,372
  • 2
  • 8
  • 33
  • Yes, this holds true for mobile devices. Is there any way to add HTTP headers in this API request as of 2022? – webblover Jun 22 '22 at 07:05