Search code examples
javascriptangularserver-side-renderingheatmapangular-ssr

Integratin CalHeatMap into Anguar app with SSR


I try to integrate CalHeatMap https://cal-heatmap.com/docs/getting-started/quickstart

into my app:

import { Component } from '@angular/core';
import { NgIconComponent, provideIcons } from '@ng-icons/core';
import { matWavingHandOutline } from '@ng-icons/material-icons/outline';
import CalHeatMap from 'cal-heatmap';

@Component({
  selector: 'app-dashboard-summary',
  standalone: true,
  imports: [NgIconComponent],
  templateUrl: './dashboard-summary.component.html',
  styleUrl: './dashboard-summary.component.css',
  viewProviders: [provideIcons({ matWavingHandOutline })],
})
export class DashboardSummaryComponent {
  ngOnInit() {
    let cal = new CalHeatMap();
    // cal.paint({});
  }
}

but when i try to call

cal.paint({});

i got:

ReferenceError: document is not defined

that comes that:

import {Selection, root} from "./selection/index.js";

export default function(selector) {
  return typeof selector === "string"
      ? new Selection([[document.querySelector(selector)]], [document.documentElement])
      : new Selection([[selector]], root);
}

so i tried:

import { JSDOM } from 'jsdom';
import { Selection, root } from './selection/index.js';

export default function(selector) {
  // Jeśli jest to Node.js, użyj jsdom do stworzenia dokumentu
  if (typeof document === "undefined") {
    const { window } = new JSDOM();
    global.document = window.document;
    global.window = window;
  }

  return typeof selector === "string"
      ? new Selection([[document.querySelector(selector)]], [document.documentElement])
      : new Selection([[selector]], root);
}

but i still get this error. Do you have any idea how to integrate it into the SSR app?


Solution

  • You can simply use afterNextRender which runs only on the browser.

    Since the server does not have a document or window object.

    export class DashboardSummaryComponent {
      ngOnInit() {
        afterNextRender(() => {
          let cal = new CalHeatMap();
          // cal.paint({});
        });
      }
    }