6

Basically I wanted to load component html specific script file, so that script I'm going to put script file reference inside component html itself, I'm seeing that inner script file has been ignored while rendering component html on page.

Component

import { Component } from '@angular/core';
@Component({
  selector: 'my-app',
  templateUrl: 'test.html'
})
export class AppComponent { }

test.html

<div>
  <h1>My First Angular 2 App</h1>
</div>
<script src="test.js"></script>

Above is my code what I tried & I already have test.js there in place.

Plunkr Here

Is there any way to load component specific javascript file with component OR with its html?

Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299

1 Answers1

11

Working Plunker

Security

It looks like Angular takes out script tags from Html templates.

From the Angular Docs:

It removes the <script> tag but keeps safe content, such as the text content of the <script> tag

Angular provides methods to bypass security, but for your use case it looks like a service would be helpful.

Services

The preferred way to include your own custom script in your component from a separate dedicated file would be to create a service.

I took the code from your Plunker's script.js file and put it into a service like this:

// File: app/test.service.ts
import { Injectable } from '@angular/core';

@Injectable()
export class TestService {
    testFunction() {
      console.log('Test');
    }
}

Then I imported the service and called the custom code like this:

// File: app/app.component.ts
import { Component, OnInit } from '@angular/core';
import { TestService } from './test.service';

@Component({
  selector: 'my-app',
  templateUrl: 'test.html',
  providers: [TestService]
})
export class AppComponent implements OnInit {
  constructor(private testService: TestService) {}
  ngOnInit() {
    this.testService.testFunction();
  }
}

Lifecycle hooks

If you want to call your service's custom code at a specific point you can take advantage of lifecycle hooks. For example you can call your code using the ngAfterViewInit() instead of ngOnInit() if you want to wait until the view has loaded.

adriancarriger
  • 2,970
  • 3
  • 19
  • 26
  • Make sense, but I can't put that code in service, because I have many pages like such with different javascript code.. can't I bypass a security for perticular component? – Pankaj Parkar Jul 02 '16 at 21:29
  • 1
    Is it for a 3rd party library? If so, your question might be similar to [this](http://stackoverflow.com/questions/34489916/load-external-js-script-dynamically-in-angular-2). – adriancarriger Jul 02 '16 at 21:43
  • seems interesting & helpful, will look at it later, Thanks :) – Pankaj Parkar Jul 02 '16 at 21:53
  • That could would not be a third party code.. that would be plain JavaScript code for that particular component, and it will vary component by component – Pankaj Parkar Jul 02 '16 at 22:13
  • 1
    So it sounds like it's your code that you want to reuse in an Angular 2 project? If you just want to get it working you could probably put it in your index.html file and it would be available globally, but you might miss out on some of Angular's modularity. Also you could refactor your code into an [Angular 2 module](http://blog.angular-university.io/how-to-create-an-angular-2-library-and-how-to-consume-it-jspm-vs-webpack/) and import that into your component. – adriancarriger Jul 02 '16 at 22:26
  • I think I need to refactor it to the es6 modules then I can easily import them inside a controller, I see that sounds good option, Thanks ;) – Pankaj Parkar Jul 02 '16 at 22:29
  • 1
    what if I have a large library like d3.js that I would like it to be downloaded only when the component that requires it is loaded? – kyw Jan 20 '17 at 09:19
  • @kyw The Angular way of integrating D3 into AngularJS is by using a directive. You can start with making a new module with the name 'd3': http://www.ng-newsletter.com/posts/d3-on-angular.html – Eugene Kardash Apr 28 '17 at 06:00