Following this link I was able to load external js files as following:
import { Component, OnInit, Renderer2 } from "@angular/core";
import { ScriptService } from "@app/element-types/_services/script.service";
const scriptPath = 'https://apis.google.com/js/api.js';
declare let gapi: any;
@Component({
selector: 'app',
templateUrl: './app.component.html',
standalone: true
})
export class AppComponent implements OnInit {
constructor(
private renderer: Renderer2,
private scriptService: ScriptService
) {}
ngOnInit() {
const scriptElement = this.scriptService.loadJsScript(this.renderer, scriptPath);
scriptElement.onload = () => {
console.log('Google API Script loaded');
gapi.load('client', 'init');
}
}
}
And ScriptService.ts
import {Inject, Injectable, Renderer2} from "@angular/core";
import { DOCUMENT } from "@angular/common";
@Injectable({
providedIn: 'root'
})
export class ScriptService {
constructor( @Inject(DOCUMENT) private document: Document) {}
public loadJsScript(renderer: Renderer2, src: string): HTMLScriptElement {
const script = renderer.createElement('script');
script.type = 'text/javascript';
script.src = src;
renderer.appendChild(this.document.body, script);
return script;
}
}
So far so good, but I would like to change the code and instead of giving a url, I provide a script code and run it directly as follows:
const scriptPath = 'https://apis.google.com/js/api.js';
---> change to
const scriptPath = "alert('Hello world');";
The error that I get now is:
Uncaught SyntaxError: expected expression, got '<'
So I want to know if it is possible, to do so.
P.s. I don't want to define a js file in assets and then import it in the angular component and then call it.
If you want to create script element with custom code in it, you can change your service method like this:
public loadJsScript(renderer: Renderer2, src: string): HTMLScriptElement {
const script = renderer.createElement('script');
script.type = 'text/javascript';
script.text = 'code you want to insert into script element';
renderer.appendChild(this.document.body, script);
return script;
}
So, you can do it by removing setting src
and instead set text
attribute. Little about HTMLScriptElement.text
attribute from docs:
A string that joins and returns the contents of all
Text
nodes inside the<script>
element (ignoring other nodes like comments) in tree order. On setting, it acts the same way as theNode.textContent
property.
Little note: as I will show in snippet, you can use text
, textContent
, innerText
and innerHTML
attributes to set code into script
element but I would recommend to stick to the docs and use text
attribute since that's it's use.
Example:
const script1 = document.createElement("script");
const script2 = document.createElement("script");
const script3 = document.createElement("script");
const script4 = document.createElement("script");
script1.text = "console.log(1);";
script2.textContent = "console.log(2);";
script3.innerText = "console.log(3);";
script4.innerHTML = "console.log(4);";
document.body.appendChild(script1);
document.body.appendChild(script2);
document.body.appendChild(script3);
document.body.appendChild(script4);