Di Angular 19 (standalone), kamu bisa memuat file JavaScript eksternal hanya saat komponennya aktif dengan cara berikut:

1. Menggunakan Renderer2

Gunakan Renderer2 untuk menambahkan <script> ke dalam ngOnInit dan menghapusnya di ngOnDestroy.

import { Component, Renderer2, ElementRef, OnInit, OnDestroy } from '@angular/core';

@Component({
  selector: 'app-example',
  templateUrl: './example.component.html',
  styleUrls: ['./example.component.css']
})
export class ExampleComponent implements OnInit, OnDestroy {
  private scriptElement?: HTMLScriptElement;

  constructor(private renderer: Renderer2, private el: ElementRef) {}

  ngOnInit() {
    this.scriptElement = this.renderer.createElement('script');
    this.scriptElement.src = 'assets/js/custom-script.js'; // Ganti dengan path JS yang ingin dimuat
    this.scriptElement.type = 'text/javascript';
    this.scriptElement.async = true;
    this.renderer.appendChild(this.el.nativeElement, this.scriptElement);
  }

  ngOnDestroy() {
    if (this.scriptElement) {
      this.renderer.removeChild(this.el.nativeElement, this.scriptElement);
    }
  }
}

Penjelasan:
  • Saat komponen aktif (ngOnInit), Angular akan memuat file JS.
  • Saat komponen dihancurkan (ngOnDestroy), Angular akan menghapus <script> tersebut agar tidak membebani aplikasi.
2. Menggunakan Lazy Loading dengan Dynamic Import

Jika file JS memiliki fungsi yang ingin dijalankan dalam komponen, kamu bisa menggunakan dynamic import.
import { Component, OnInit, OnDestroy } from '@angular/core';

@Component({
  selector: 'app-example',
  templateUrl: './example.component.html',
  styleUrls: ['./example.component.css']
})
export class ExampleComponent implements OnInit, OnDestroy {
  private customScript?: any;

  async ngOnInit() {
    this.customScript = await import('assets/js/custom-script.js');
    if (this.customScript.init) {
      this.customScript.init(); // Jika file JS memiliki fungsi init, panggil di sini
    }
  }

  ngOnDestroy() {
    if (this.customScript && this.customScript.cleanup) {
      this.customScript.cleanup(); // Hapus event listener jika perlu
    }
  }
}

Keuntungan:
  • File hanya dimuat ketika dibutuhkan.
  • Bisa langsung memanggil fungsi di dalam JS tanpa menambahkan <script> manual.

Mana yang Harus Dipilih?
✅ Jika hanya ingin memuat file eksternal di DOM → Gunakan Renderer2
✅ Jika ingin langsung mengakses fungsi dari JS → Gunakan dynamic import


Contoh kasus :
Untuk menjalankan DataTables.js atau Chart.js di Angular 19, metode terbaik tergantung pada cara kamu menggunakannya. Berikut perbandingan dua metode yang paling cocok:

1. Menggunakan Renderer2 (Skrip Eksternal di Assets)
🔹 Cocok jika:
  • Kamu ingin memuat file JS hanya saat komponen aktif.
  • File JS tidak perlu dieksekusi langsung dalam TypeScript.
Cara Implementasi
Tambahkan script ke dalam ngOnInit dan hapus di ngOnDestroy.

Example: Load DataTables.js
import { Component, Renderer2, ElementRef, OnInit, OnDestroy } from '@angular/core';

@Component({
  selector: 'app-example',
  templateUrl: './example.component.html',
  styleUrls: ['./example.component.css']
})
export class ExampleComponent implements OnInit, OnDestroy {
  private scriptElement?: HTMLScriptElement;

  constructor(private renderer: Renderer2, private el: ElementRef) {}

  ngOnInit() {
    this.scriptElement = this.renderer.createElement('script');
    this.scriptElement.src = 'assets/js/datatables.min.js'; // Sesuaikan path
    this.scriptElement.type = 'text/javascript';
    this.scriptElement.async = true;
    this.scriptElement.onload = () => {
      // Inisialisasi DataTables setelah script dimuat
      ($('#myTable') as any).DataTable();
    };
    this.renderer.appendChild(this.el.nativeElement, this.scriptElement);
  }

  ngOnDestroy() {
    if (this.scriptElement) {
      this.renderer.removeChild(this.el.nativeElement, this.scriptElement);
    }
  }
}

Keuntungan:
  • File hanya dimuat saat komponen aktif.
  • Tidak perlu menginstal library ke dalam proyek.

Kekurangan:
  • Harus memastikan bahwa elemen (#myTable) sudah tersedia sebelum menginisialisasi.
  • Kurang fleksibel jika ingin mengakses DataTables di TypeScript.
2. Menggunakan Dynamic Import (import())
🔹 Cocok jika:
  • Kamu ingin menggunakan fungsi JS langsung di TypeScript.
  • Library Chart.js atau DataTables.js sudah diinstal melalui npm.

Install Library  :
npm install chart.js datatables.net

Example: Load Chart.js di TypeScript

import { Component, OnInit, OnDestroy, ElementRef, ViewChild } from '@angular/core';
import { Chart, ChartConfiguration, ChartType } from 'chart.js';

@Component({
  selector: 'app-chart',
  template: '',
  styleUrls: ['./chart.component.css']
})
export class ChartComponent implements OnInit, OnDestroy {
  @ViewChild('chartCanvas', { static: true }) chartCanvas!: ElementRef;
  private chartInstance?: Chart;

  async ngOnInit() {
    const { Chart } = await import('chart.js');
    this.chartInstance = new Chart(this.chartCanvas.nativeElement, {
      type: 'bar' as ChartType,
      data: {
        labels: ['A', 'B', 'C'],
        datasets: [{ label: 'Sample Data', data: [10, 20, 30], backgroundColor: 'blue' }]
      }
    });
  }

  ngOnDestroy() {
    this.chartInstance?.destroy();
  }
}

Keuntungan:
  • Lebih Angular-friendly, karena library bisa diakses langsung dari TypeScript.
  • Tidak bergantung pada DOM, karena bisa diinisialisasi dari kode.

Kekurangan:
  • Harus menginstal library ke dalam proyek.
  • Performa sedikit lebih berat jika dibandingkan hanya memuat script eksternal.
Kesimpulan: Pilih Mana?

MetodeKeuntunganKekuranganCocok untuk
Renderer2 (Script Tag)Tidak perlu instal library, mudah diterapkanKurang fleksibel untuk AngularDataTables.js dengan HTML Table
Dynamic Import (import())Angular-friendly, bisa diakses di TypeScriptPerlu instal libraryChart.js atau DataTables jika ingin kendali lebih banyak di TypeScript

🔹 Gunakan Renderer2 jika hanya ingin load script eksternal tanpa banyak interaksi.
🔹 Gunakan Dynamic Import jika ingin lebih fleksibel dan mengikuti best practice Angular.