Search code examples
angularangular-servicesangular-components

Angular component not loading in the browser due to Observable subscription


In this component when I call the getCurrentSalahOrIqamah function in the ngOninit so my component is not loaded in the browser. and keep stuck. I tried with both lazyloaded eager loaded component but the issue was not solved.

import { Component, OnDestroy, OnInit } from '@angular/core';
import { SubSink } from 'subsink';
import { interval, map } from 'rxjs';

@Component({
      selector: 'app-timingscreen',
      standalone: true,
      imports: [],
      providers: [],
      templateUrl: './timingscreen.component.html',
      styleUrl: './timingscreen.component.scss'
    })
export class TimingscreenComponent {
  private subs = new SubSink()

ngOnInit(): void {
    this.getCurrentSalahOrIqamah()
  }
  getCurrentSalahOrIqamah() {
    this.subs.sink = interval(1000).pipe(
      map(() => {
        const date = new Date();
        return date.getHours() * 3600 + date.getMinutes() * 60 + date.getSeconds();
      })
    ).subscribe(
      {
        next:(timeInSeconds:number)=>{
          console.log(timeInSeconds)
        }
      }
    )
    
  }
  ngOnDestroy(): void {
    this.subs.unsubscribe()
  }

}

Angular version is: "^17.2.0" Rxjs version is : "~7.8.0"


Solution

  • In Angular 17, Server-Side Rendering (SSR) is enabled by default. However, it may encounter difficulties completing the rendering process if your code includes intervals that constantly change. The following code can help resolve this issue:

    import { isPlatformBrowser } from '@angular/common';
    import { Component, DestroyRef, OnInit, PLATFORM_ID, inject } from '@angular/core';
    import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
    import { interval, map } from 'rxjs';
    import { SubSink } from 'subsink';
    
    @Component({
        selector: 'app-timingscreen',
        standalone: true,
        imports: [],
        providers: [],
        templateUrl: './timingscreen.component.html',
        styleUrl: './timingscreen.component.scss'
    })
    export class TimingscreenComponent implements OnInit {
        private subs = new SubSink()
    
        private destroyRef = inject(DestroyRef);
        private platformId = inject(PLATFORM_ID);
    
        ngOnInit(): void {
            if (isPlatformBrowser(this.platformId)) {
                this.getCurrentSalahOrIqamah();
            }
        }
        getCurrentSalahOrIqamah() {
            this.subs.sink = interval(1_000).pipe(
                takeUntilDestroyed(this.destroyRef),
                map(() => {
                    const date = new Date();
                    return date.getHours() * 3_600 + date.getMinutes() * 60 + date.getSeconds();
                })
            ).subscribe(
                {
                    next: (timeInSeconds: number) => {
                        console.log(timeInSeconds);
                    }
                }
            );
        }
    }