0

I have a sidebar Angular component which uses a local script sidebar.js. In src\app\sidebar\sidebar.component.ts, I tried loading sidebar.js as follows:

  ngAfterViewInit(): void {
    const s = document.createElement('script');
    s.type = 'text/javascript';
    s.src = 'src/app/sidebar/sidebar.js';
    console.log('creating external script: ' + s.src);
    this.elementRef.nativeElement.appendChild(s);
  } 

I got this error:
http://localhost:4201/src/app/sidebar/sidebar.js net::ERR_ABORTED 404 (Not Found)

Yes, I have this line in angular.json as well:

        "scripts": [
...
          "src/app/sidebar/sidebar.js"
        ]

And the following also failed with a 404:

s.src = 'sidebar.js';

Unfortunately since sidebar component resides in an Angular module that I am building for a customer, I cannot put sidebar.js in /assets as suggested in My Local JavaScript file is not loaded in Angular 2 . The /assets directory resides in my customer's code. Also, sidebar.js contains this logic :

const _R = document.querySelector('[type=range]');
_R.style.setProperty('--val', +_R.value);
_R.style.setProperty('--max', +_R.max);
_R.style.setProperty('--min', +_R.min);

which depends on sidebar.component (which resides in my module):

  <input
    class="border-0 slider"
    type="range"
    min="10"
    [title]="scale"
    step="5"
    [(ngModel)]="scale"
    max="200"
    orient="vertical"
    list="tickmarks"
  />

Yes, I realize many similiar questions were asked and answered on SO:
angular2: including thirdparty js scripts in component
script tag in angular2 template / hook when template dom is loaded

but none of them address the aspect that sidebar.js and index.html are in two different modules.

letsintegreat
  • 3,328
  • 4
  • 18
  • 39
fritz6
  • 73
  • 1
  • 16

1 Answers1

1

Your script snippet does not "depend" on your component in your example snippet. You are requesting any input with type "range" in the whole web page (document's root) and that is not necessarily your component. (If you have 10 input[type="range"] in your page, the script will have to handle that somehow, or it will only get the first one).

The way to do what you are trying to do IS to put it in the assets folder. If that is forbidden by any project rule, you have two options:

  1. Upload your sidebar.js file into a different server or a different path and host it from there. Since it seems you don't have control over the files in your customer server, you can't make the assumption that the /src/app/ directory is present (since it is not necessary to run the app after it has been built)

  2. Transform your .js file into a typescript file (.ts) and import it so that typescript can compile it.

To transform it into a .js file, just rename the file to sidebar.ts and, at the file you want to include it, import for side effects only

What I recommend is that you wrap your file in a callable function that receives your component reference as a parameter so that you can specify which element is to related to as opposed to let it find in the document root but I suspect that would involve messing with the internals of the sidebar.js file. However if the sidebar file is a library or a module, this might be too time-consuming.