2

So I'm working on a forum and a part of that forum is a section where I count how many members are currently online (registered and visitors). When people enter the forum I activate the code in my ngOninit() to add 1 to the document in my database that counts the amount of people currently using the forum. When I leave the forum, it activates the ngOnDestroy() and subtracts one.

This adding 1 to the DB document seems to work fine. The problem however is that when I refresh the page with F5, that it doesn't subtract 1. I tried by adding window.onbeforeunload = () => this.ngOnDestroy(); in my ngOnInit, but the problem didn't get solved this way. It keeps adding members even though it is just me refreshing the page a couple of times. This problem only occurs when I refresh, it's not an issue when I navigate through my website.

Can anyone make a suggestion on how to fix this?

forumCount.component.ts

export class ForumCountComponent implements OnInit, OnDestroy{

    data;
    ngUnsubscribe = new Subject();

    constructor(private authService: AuthenticationService, private forumService: ForumService){

    }

    ngOnInit(){
        let loggedIn = this.authService.isLoggedIn();

        this.forumService.forumCountPlus(loggedIn)
            .takeUntil(this.ngUnsubscribe)
            .subscribe((data) => {
                this.data = data;
            });

        window.onbeforeunload = () => this.ngOnDestroy();
    }

    ngOnDestroy(){
        console.log('activated ngOnDestroy');
        let loggedIn = this.authService.isLoggedIn();

        this.forumService.forumCountMin(loggedIn)
            .takeUntil(this.ngUnsubscribe)
            .subscribe((data) => {
                this.data = data;
                this.ngUnsubscribe.next();
                this.ngUnsubscribe.complete();
            })
    }
}

forumCount.component.html

<div class="row justify-content-center mb-5">
    <div class="col-md-8">
        <div class="card">
            <p class="card-header">Who's Online?</p>
            <div class="card-body">
                <p class="card-text">In total there are {{data?.total}} users online :: {{data?.registered}} registered and {{data?.guests}} guests
                    <br/>
                    <br/>
                    The highest amount of online users was {{data?.highestNumber.num}} on {{data?.highestNumber.date | amDateFormat:'MMMM Do YYYY, h:mm:ss a'}}</p>
            </div>
        </div>
    </div>
    <div class="col-md-2">
    </div>
</div>
tilly
  • 2,229
  • 9
  • 34
  • 64
  • 2
    Maybe [this answer](https://stackoverflow.com/a/40468409/8371135) will clarify what's going on – Rodrigo Ferreira Jul 24 '18 at 14:02
  • The application will be destroyed by the browser, so onDestroy won't be called – Rodrigo Ferreira Jul 24 '18 at 14:03
  • When you refresh the page ngOnInit() will be called. You need to leave the page to trigger ngOnDestroy() – kboul Jul 24 '18 at 14:05
  • @RodrigoFerreira It mentions the window.onbeforeunload as well. I assume that it would be better to activate something in a service through this than to activate the ngOnDestroy()? Wait, I'll try it out. – tilly Jul 24 '18 at 14:08
  • @kboul People will still be able to refresh the page, so I need to find a solution for that or the counts won't be correct. – tilly Jul 24 '18 at 14:08
  • 1
    Ok, so I fixed it. Instead of calling the ngOndestroy() in window.onbeforeunload I created a new function that called the service and then called that function in my window.onbeforeunload callback as well as in my ngOnDestroy() for when people would leave the page through navigation. – tilly Jul 24 '18 at 14:14

1 Answers1

1

Ok guys,

thanks to Rodrigo's advice I was able to fix it.

import {Component, OnDestroy, OnInit} from "@angular/core";
import {AuthenticationService} from "../auth/auth.service";
import {ForumService} from "./forum.service";
import {Subject} from "rxjs/Subject";


@Component({
    selector: 'forum-count',
    templateUrl: 'forum-count.component.html',
    styleUrls: ['forum-count.component.css']
})

export class ForumCountComponent implements OnInit, OnDestroy{

    data;
    ngUnsubscribe = new Subject();

    constructor(private authService: AuthenticationService, private forumService: ForumService){

    }

    ngOnInit(){
        let loggedIn = this.authService.isLoggedIn();

        this.forumService.forumCountPlus(loggedIn)
            .takeUntil(this.ngUnsubscribe)
            .subscribe((data) => {
                this.data = data;
            });

        window.onbeforeunload = () => {
            this.subtractOne()
        };
    }

    subtractOne(){
        let loggedIn = this.authService.isLoggedIn();

        this.forumService.forumCountMin(loggedIn)
            .takeUntil(this.ngUnsubscribe)
            .subscribe((data) => {
                this.data = data;
                this.ngUnsubscribe.next();
                this.ngUnsubscribe.complete();
            })
    }

    ngOnDestroy(){
        this.subtractOne();
    }


}

I simply created this subtractOne method instead of calling the ngOnDestroy and now it works like a charm.

tilly
  • 2,229
  • 9
  • 34
  • 64
  • 1
    This is a solution for develop stage, I dont think you have to update your DB every time. Just imagine some1 sitting on your site and hitting refresh nonstop (im not even talking about scripts or something fancy), thats so much calls to the servers. Try to implement some kind of service which takes a value and add its to a timer or something like that, lets say 5-10 secs to distinct a change in the value. – dAxx_ Jul 24 '18 at 14:23
  • Thanks for the advice @dAxx_ – tilly Jul 24 '18 at 14:46