0

I have a set up check-boxes that many different users can use simultaneously. I poll the server to get the check-box's status every 5 seconds. The problem is that sometimes when I check a box (and make a post request) it is while a get request is being resolved and the view is updating. This essentially "misses" the checkbox click and an unchecked box remains unchecked when a user clicks it. Is there a way around this? is there a way to tell my observable "hey, stop updating the view from the get request when I check my box". I tried unsubscribing to the observable at the beginning of the click() function and then resubscribing after, but aggravated the problem much more.

Brief example of my code: Controller:

ngOnInit(): void {

    // get our data immediately when the component inits
    this.checklistService.getchecklist()
        .first() // only gets fired once
        .subscribe(data => {
            this.checklist = data;
        });

    // get our data every subsequent 5 seconds
    this.subscription.add(
        IntervalObservable.create(5000)
            //.takeWhile(() => this.alive) // only fires when component is alive
            .subscribe(() => {
                this.checklistService.getchecklist()
                    .subscribe(data => {
                        this.checklist = data;
                    });
            })
    );
}
checkOrUncheck(outgoingItemCheck: ChecklistItem) {
    if (outgoingItemCheck.CheckListStepId == null) {
        console.log('null ItemId found at checklist with a description of: ' + outgoingItemCheck.description);
    }
    else {
        if (outgoingItemCheck.Checked == null) {
            outgoingItemCheck.Checked = true;
        }
        else {
            outgoingItemCheck.Checked = !outgoingItemCheck.Checked;  //switch from true to false, or false to true
        }

        this.checklistService.checkOrUncheck(outgoingItemCheck)
            .then(checklistItemFromServer => {
                this.checklistItem = checklistItemFromServer;
            });  
    }
}

Service

  getchecklist(): Observable<ChecklistItem[]> {
      return this.http.get(this.checklistUrl).map(response => response.json());
  }

HTML

<label class="custcol3 form-check-label columnchecklistheader columncentertext">
    <div *ngIf="clItem.Checked; else notCheckBlock">
        <input class="form-check-input" type="checkbox" checked="checked" (click)="checkOrUncheck(clItem)" value="" style="cursor: pointer;">
    </div>
    <ng-template #notCheckBlock>
        <label>
            <input class="form-check-input" type="checkbox" (click)="checkOrUncheck(clItem);" value="" style="cursor: pointer;">
        </label>
    </ng-template>
</label>
Goku
  • 1,565
  • 1
  • 29
  • 62

2 Answers2

0

hum... I think this is more a problem in the application, which is needed in this case.

sancelot
  • 1,905
  • 12
  • 31
  • can you expand on what this means? – Goku Aug 04 '17 at 14:15
  • I need a minimal example of your code to help correct it. – sancelot Aug 04 '17 at 14:31
  • I added my code in hopes you could provide some feedback – Goku Aug 04 '17 at 15:10
  • Regarding the html code, I would prefer avoid usage of ng-template and have only one , trying a different implementation, being sure we are always refering the same input component .Next, I would protect the shared resource variables access with a mutex or semaphore , between service call and checkorUncheck func. Because when you told the click is really missed , I am not sure to really understand.(can console.log() in checkOrUncheck being output ?) – sancelot Aug 04 '17 at 20:46
0

So you need to ensure that a client's post request can't "cross" with a poll response from the server.

I think your simplest solution (or at least part of it) will be for post requests and poll requests not to be independent of each other, ie. embed your "post request" in the next poll request.

To make the schema as responsive as possible, you probably also need to make the next poll request as soon as possible after a checkbox is clicked - ie bring the next poll request forward.

But please note, this only answers the question posed. Another consideration is the assurance that all clients display the same "agreed picture". The status of each check-box must not be allowed to get out of phase with respect to that at any other client.

You may need a long-polling approach in order to ensure that the server, not any particular client, is in control.

Roamer-1888
  • 19,138
  • 5
  • 33
  • 44
  • do you know of any angular 2+ examples or documentation with long-polling? – Goku Aug 04 '17 at 19:45
  • @adamkim, sorry I don't. Read through [the article I linked to](https://stackoverflow.com/questions/11077857/what-are-long-polling-websockets-server-sent-events-sse-and-comet). I'm actually a bit old fashioned in advocating long-polling these days. You will see in the article that, with the advent of HTML5, things have moved on a bit. – Roamer-1888 Aug 05 '17 at 04:18