Is there a way to utilize the 'interval' Rxjs function without triggering the Change Detection routine?

My goal is to display the live server time in my application. To achieve this, I created a component that utilizes the RXJS 'interval' function to update the time every second. However, this approach triggers the Change Detection routine every second!

Is there a way to update the time without causing change detection to run?

Below is the code for my component:

server-time.component.ts:

export class ServerTimeComponent implements OnInit {
  serverTime: Date;
  serverDatetime: InfoDatetime;

  constructor(private infoService: InfoService) {}

  ngOnInit() {
    this.getServerDate();

    // Increase time by interval
    interval(1000).subscribe(() => {
      // Skip if the time is not ready
      if (this.serverTime === undefined) {
        return;
      }

      // Update the time
      this.serverTime = new Date(this.serverTime.getTime() + 1000);
      // If it's midnight, get the date again
      if (
        this.serverTime.getHours() === 0 &&
        this.serverTime.getMinutes() === 0 &&
        this.serverTime.getSeconds() < 2
      ) {
        this.getServerDate();
      }
    });
  }

  getServerDate() {
    this.infoService
      .getServerDatetime()
      .subscribe((res: ApiResponse<InfoDatetime>) => {
        if (res.code === 1) {
          this.serverDatetime = res.data;

          // Create a new Date. Time part will be used
          this.serverTime = new Date('2000-01-01 ' + this.serverDatetime.time);
        }
      });
  }
}

server-time.component.html:

<span *ngIf="serverDatetime">
  <span class="ml-1">{{serverTime | date:'hh:mm:ss'}}</span>
  —
  <span class="mr-1">{{serverDatetime?.date_jalali}}</span>
</span>

To view the issue in action on stackblitz.io, click on the link below:

Thank you

Answer №1

To implement this functionality, you must make use of the NgZone runOutsideAngular method

export class ServerTimeComponent implements OnInit {
  serverTime: Date;
  serverDatetime: InfoDatetime;

  constructor(private infoService: InfoService, public zone: NgZone) {}

  ngOnInit() {
    this.getServerDate();

    // Adjust time by specified interval

    this.ngZone.runOutsideAngular( ()=> {
        interval(1000).subscribe(() => {
      // Proceed only when the time is available
      if (this.serverTime === undefined) {
        return;
      }

      // Update the time
      this.serverTime = new Date(this.serverTime.getTime() + 1000);
      // If it's midnight, fetch the date again
      if (
        this.serverTime.getHours() === 0 &&
        this.serverTime.getMinutes() === 0 &&
        this.serverTime.getSeconds() < 2
      ) {
        this.getServerDate();
      }
    });

    });

  }

  getServerDate() {
    this.infoService
      .getServerDatetime()
      .subscribe((res: ApiResponse<InfoDatetime>) => {
        if (res.code === 1) {
          this.serverDatetime = res.data;

          // Generate a new Date with relevant time component
          this.serverTime = new Date('2000-01-01 ' + this.serverDatetime.time);
        }
      });
  }
}

Answer №2

Here is a helpful tip:

// To incorporate zone injection, include this in the constructor
constructor(public zone: NgZone, ...args) { }

Utilize the 'zone' to trigger change detection for variables.

interval(1000).subscribe(() => {
    // Skip if the time is not ready
    if (this.serverTime === undefined) {
      return;
    }

    // Update the time using zone
    this.zone.run(() => this.serverTime = new Date(this.serverTime.getTime() + 1000))
    // If it's midnight, get the date again
    if (
      this.serverTime.getHours() === 0 &&
      this.serverTime.getMinutes() === 0 &&
      this.serverTime.getSeconds() < 2
    ) {
      this.getServerDate();
    }
});

Answer №3

It appears you may have forgotten to clear the previous interval or unsubscribe from it. Consider revising your code like this:

if(this.interval !== undefined) { 
  clearInterval(this.interval); //this.interval.unsubscribe();
}
this.interval =  interval(1000).subscribe(() => {

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The nightwatch.js script is halting operations once the test suite has been completed

Recently, I've implemented functional test automation using nightwatch.js. However, I encountered an issue where the test pauses after the test suite is completed, failing to end the process. Below is a snippet of the code: var afterSuite = function( ...

Error sound produced when detecting KeyCode on the keyboard

I'm currently working on a JavaScript project that involves capturing keyboard input. However, I'm encountering an issue where every time the user presses a key, it triggers an error sound. Is there a way to disable this sound? ...

I am looking to append a new value to an array within the state in React

development environment ・ react ・ typescript In this setup, state groups are stored as arrays. If you want to add a group to the array of groups when the onClickGroups function is called, how should you go about implementing it? interface ISearc ...

Dropdown menu utilizing processing API and interacting with AJAX and DOM manipulation

My API data is not showing up in the dropdown menu. If I use ?act=showprovince, I can see the result. example.html <head> <link rel="stylesheet" type="text/css" href="css/normalize.css"> <link rel="stylesheet" type="text/css" hr ...

The placement of term.js is always at the bottom of the body

Seeking help with JavaScript as a beginner, I am facing issues with placing an element in my project. Although I can easily open terminals and write to them, every time I create one, it gets appended at the end of the body. I referred to this example for ...

Guide to converting a specific tag into div using Javascript

I am working with some HTML code that includes a div: <div class="myDiv"> <a href="" title="">My link</a> <p>This is a paragraph</p> <script>//This is a script</script> </div> Additionally, I ha ...

Prevent form validation in ReactiveForm when a hidden field is present

I am encountering an issue with the validation of a button in my form. The button is disabled until the form is valid, which works perfectly when all fields are visible. However, if a field is hidden due to a condition (ngIf), the validation still occurs. ...

Modules failing to load in the System JS framework

Encountering a puzzling issue with System JS while experimenting with Angular 2. Initially, everything runs smoothly, but at random times, System JS struggles to locate modules... An error message pops up: GET http://localhost:9000/angular2/platform/bro ...

Is there a way to transmit the wellness update of my Angular application to Akamai?

I currently have an Angular application and am utilizing the Akamai CDN. Can you advise me on the most effective method to relay the health status (200, 500, etc.) to Akamai? I want to ensure that in case it doesn't return a 200 code, Akamai is able t ...

When a new ajax function is added, the original Ajax code stops functioning

I've been working on getting the code below to function properly. It seems that when I test the code, two validation functions are working correctly. However, when I include the validateUsername() function along with the if statement in the code, ever ...

Guide to receiving dynamic argument variables in jQuery using $.get

I am currently working on developing an Ajax function call. In this function, the argument q will be dynamically defined, and the $.get method will return either true or false based on the data received from the Ajax call. <a href="any.php" class ...

Angular2 form builder generating dynamic forms based on results of asynchronous calls

When creating my form, I encountered a challenge with passing the results of an asynchronous call to the form builder. This is what I have attempted: export class PerformInspectionPage implements OnInit { checklists: any; inspectionform: FormGroup; n ...

JQuery does not recognize $(this) after the HTML has been altered

I manage a website that includes several href links and 2 buttons that have the ability to modify those links dynamically. <div class="links"> <p class="hlCategory">Classical Mechanics</p> <ul> <li><a cl ...

Issue with Angular routing not functioning properly post form submission

Recently, I created a contact form using Angular for the frontend and NodeJs with Nodemailer for the backend. However, I encountered an issue where after submitting the form, instead of redirecting to the default page set in the app, the page remains on th ...

"Put Phonegap on hold for a bit and disable landscape mode

I am currently using Phonegap to develop an Android game. My project includes a lobby feature where players can search for opponents and engage in chat with other players. Once a player has found their opponent, they can commence playing the game together ...

Tips for updating information when a button is chosen

Hello everyone, I need some help with a form that has three select buttons. The button labeled "Distribute" is already selected when the page loads, and it contains information about full name, password, and location. How can I use JavaScript to create a c ...

The issue with Angular-gettext is that it fails to update dynamically generated strings in the code

Whenever I try to set the language using the code gettextCatalog.setCurrentLanguage(langString);, it doesn't seem to affect my side-nav menu. My side menu has two possible states: expanded or collapsed, and I use ng-include to control its content base ...

Utilizing type guards in prop functions for conditional rendering within React TypeScript adds an extra layer

In my code, I am conditionally rendering a Button. However, I encountered an issue on line 7 where TypeScript is indicating that the first parameter of the exportExcel function may be null even though it should not be, considering the conditional render lo ...

What impact does setting a variable equal to itself within a Dom Object have?

Within my code example, I encountered an issue with image sources and hrefs in a HTML String named tinymceToHTML. When downloading this html String, the paths were set incorrectly. The original image sources appeared as "/file/:id" in the String. However, ...

A single button that performs multiple actions with just one click

Summary: Seeking assistance in implementing a button that triggers three different actions upon being clicked thrice. Detailed description: On one page of my website, there is an introduction with text and images. I currently have a button that switches t ...