Home > Net >  Rxjs timer restarts after unsubscribe
Rxjs timer restarts after unsubscribe

Time:12-12

I started making a simple game to test reflexes. When the red rectangle turns green, the player must click on the figure and the result is displayed. The problem is that after clicking on the rectangle the timer starts again.I use unsubscribe for this, but no results.

Example: https://stackblitz.com/edit/angular-ivy-w8uejd?file=src/app/app.component.ts

Code:

HTML

<div (click)="onRegtangleClicked()"  id="rectangle"></div>
<div >
    <button (click)="onStartClicked()" >Start</button>
</div>
<p >You score is:  {{time}} (lower is better)</p> 

SCSS

.rectangle {
    position: relative;
    height: 500px;
    width: 100%;
    background-color: rgb(255, 0, 0);
    cursor: pointer;
  }
.button{
    margin-left: 40%;
    margin-top: 2%;
    position: relative;
}
.text{
    font-size: large;
    position: relative;
    margin-left: 40%;
}

typescript

import { Component, OnInit } from '@angular/core';
import { timer } from 'rxjs';

@Component({
  selector: 'app-reflexgame',
  templateUrl: './reflexgame.component.html',
  styleUrls: ['./reflexgame.component.scss'],
})
export class ReflexgameComponent implements OnInit {
  time: number = 0;
  subscription: any;

  constructor() {}

  ngOnInit(): void {}

  onStartClicked() {
    let randomNumber:number = Math.random() * 5;
    setInterval(() => {
      document.getElementById('rectangle')!.style.backgroundColor = 'green';
      this.observableTimer();
    }, randomNumber * 1000);
  }
  onRegtangleClicked() {
    this.subscription.unsubscribe();
  }
  observableTimer() {
    this.subscription = timer(0, 1).subscribe((val) => {
      this.time = val;
    });
  }
}

I don't know where I'm wrong?

CodePudding user response:

The timer is restarting again and again because in the method onStartClicked() you are using setInterval. The logic you define inside an interval is executed continuously every x seconds until you call the clearInterval(theIntervalToClear).

In your case, you should use a setTimeout to only trigger the logic once after x seconds pass.

cheers

CodePudding user response:

The reason for your code break is because

  1. You are calling unsubscribe() even before you creating a subscription: to fix that you can add a flag so to know whether the subscription is active or not.
  2. When you create an interval it is better to clear the interval.

Got it working for me with both the logic, give it a try

  • Related