Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to run an external js code in angular

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.

like image 411
user6781 Avatar asked Nov 01 '25 14:11

user6781


1 Answers

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 the Node.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);
like image 63
Milos Stojanovic Avatar answered Nov 03 '25 02:11

Milos Stojanovic



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!