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

Modifying the date format of the ag-Grid date filter

On my Angular 5.2.11 application, I utilize ag-grid to showcase a table. The date column is configured with the default date filter agDateColumnFilter as per the documentation. After enabling browserDatePicker: true, the Datepicker displays dates in the ...

Unable to retrieve context value for authentication requirements

I have implemented a feature in my application where I redirect users to the login page for certain special pages if they are not logged in. The implementation involves using react-router. Here is the code snippet for my RequireAuth component: const Requir ...

Here is a way to retrieve the name of a ref object stored in an array using Vue.js 3 and Typescript

I have a Form, with various fields that I want to get the value of using v-model and assign them to ref objects. In order to populate my FormData object with this data, I require both the name and the value of the ref objects. Unfortunately, I am struggli ...

The scrolling feature is not working in NativeScript's ScrollView component

As I delve into using NativeScript with Angular to develop my debut mobile application, things have been going quite smoothly. However, a recent snag has halted my progress - the page refuses to scroll to reveal its entire content. To showcase this issue, ...

What is the best way to implement lazy loading for child components in React's Next.js?

I am exploring the concept of lazy loading for children components in React Next JS. Below is a snippet from my layout.tsx file in Next JS: import {lazy, Suspense} from "react"; import "./globals.css"; import type { Metadata } from &quo ...

JavaScript - Loading image from local file on Linux machine

I have a server running and serving an HTML page, but I am trying to display an image from a local drive on a Linux machine. I've tried using file://.., but it doesn't seem to be working for me on Ubuntu 18.04. There are no errors, the img tag ju ...

Discovering the size and count of JavaScript objects within a browser's memory

Many suggest using the Chrome Profiler Heap Snapshot to analyze memory usage, but I have found that on an empty page (no JavaScript or CSS, just HTML), it shows a heap size of 8MB and anywhere from 12 to 30 thousand objects depending on its mood. This tool ...

What is the process of implementing a page change using a GET request in JavaScript using Node.js and Express?

Within this application, users are provided with a table where they can input data. Each row in the table is equipped with an "Edit" button that, when clicked, should redirect them to a new page labeled "/update" where modifications to the specific row can ...

AngularJS: Assigning a value to an element

I am facing the challenge of automating an iframe using Selenium Webdriver and need to input a value into a text box. Here is the HTML code: <input class="ng-pristine ng-empty ng-invalid ng-invalid-required ng-valid-maxlength ng-touched" id="name" typ ...

Animation loading on React.js when the page or URL is changed

Just starting out with React and trying to incorporate a loading animation when the page/url changes on button click - check it out here: https://codesandbox.io/s/cthululel-7zmsl?fontsize=14 Successfully got the animation working on initial load, but runn ...

What are the implications of an unidentified callback function with parameters?

Check out this snippet: const fs = require('fs'); fs.readFile('foo.txt', 'utf8', (error, data) => { if (error) { throw new Error(error); } console.log(data); }); Can you figure out where the anonymous callback is recei ...

Adjust the button sizes in Ngprime

I am trying to customize my primeng buttons because they appear too large for my project. I found in the documentation that I can make them smaller by using: <p-button label="Small" icon="pi pi-check" styleClass="p-button-sm&quo ...

Is there a way to effortlessly upload numerous files in one go when browsing with jquery or JavaScript?

Currently working on a web application and looking to enable multiple file upload functionality within a single browse session, as opposed to selecting one file at a time. The goal is for users to be able to easily select multiple files with just one clic ...

Issue with React Material UI: Snackbar is closing when Dialog closes which is not the intended behavior

When using Material UI dialog, it unexpectedly closes the snackbar as well. To illustrate this strange issue, I have prepared a demonstration: https://codesandbox.io/s/react-hooks-counter-demo-v20w3 I am passing states from the parent component to the c ...

MUI Gradient Tracked Button

Take a look at this Codepen example I created. It showcases a hover effect where the gradient follows the mouse cursor. In order to achieve this effect, I have defined two CSS variables - --x and --y, to keep track of the mouse position on the button. The ...

The HTML to PDF file converter API performs well in a local environment but encounters issues when deployed on node.Js, Express.Js, html-pdf, and Azure Web Services platform

I've developed an API that converts HTML to PDF, and it works flawlessly in my local environment but encounters issues when deployed on Azure app web services. During the process of generating the PDF, the request gets stuck and eventually times out, ...

Tips for activating multiple CSS animations when scrolling

I am currently working on a project that involves multiple CSS animations. However, I am facing an issue where these animations only occur once when the page initially loads. I would like them to trigger every time the user scrolls past them, regardless of ...

What causes the NavBar to show and hide within a specific range?

Recently, I encountered a perplexing issue with my navbar. It functions correctly except for one strange behavior that has left me baffled. Why does the menu appear when I adjust the width to 631px, but disappear at 600px? And vice versa – why does it wo ...

Guide on posting an object in Angular through HTTP Post

I am attempting to send an object named Pack to my API Rest server using my Angular service. Below is the function I have set up for this task: save_pack(Pack: any){ return new Promise((resolve, reject) =>{ this.http .post("http://loca ...

How to effectively transfer a JSON object from a Python function to JavaScript using Eel, allowing you to seamlessly utilize and modify the JSON data

Let's delve into a slightly confusing question together. Have you heard of Eel? It's a Python module that lets you use functions created in Python in Javascript, and vice versa. What I want to achieve is taking a JSON object generated by a Python ...