ngx-script-loader presents a simple ScriptService for Angular apps to load 3rd party scripts programmatically.
With npm:
npm i --save ngx-script-loader
With yarn:
yarn add ngx-script-loader
Import ScriptLoaderModule to your app.
import { ScriptLoaderModule } from 'ngx-script-loader';
@NgModule{
....
imports: [
...,
ScriptLoaderModule
],You can use ScriptService to load external script inside your components or services.
import { ScriptService } from 'ngx-script-loader';
@Component({
...
})
export class ExampleComponent {
constructor(private scriptService: ScriptService) {
this.scriptService.loadScript('https://maps.googleapis.com/maps/api/js?libraries=places').subscribe(() => {
// Do something with Google Places API
});
}
}Even if you call loadScript multiple time at the same time for same url, it will inject that url once and resolve all subscribers.
import { ScriptService } from 'ngx-script-loader';
@Component({
...
})
export class ExampleComponent {
constructor(private scriptService: ScriptService) {
this.scriptService.loadScript('https://maps.googleapis.com/maps/api/js?libraries=places').subscribe(() => {
console.log("I'm ready to work with google library");
});
this.scriptService.loadScript('https://maps.googleapis.com/maps/api/js?libraries=places').subscribe(() => {
console.log("I'm ready to work with google library");
});
this.scriptService.loadScript('https://maps.googleapis.com/maps/api/js?libraries=places').subscribe(() => {
console.log("I'm ready to work with google library");
});
this.scriptService.loadScript('https://maps.googleapis.com/maps/api/js?libraries=places').subscribe(() => {
console.log("I'm ready to work with google library");
});
}
}With the example above you will see I'm ready to work with google library log 4 times but you will see only 1 script tag for requested script in the document.
When script loading has failed, onError callback of observable will be triggered.
import { ScriptService } from 'ngx-script-loader';
@Component({
...
})
export class ExampleComponent {
constructor(private scriptService: ScriptService) {
this.scriptService.loadScript('https://connect.facebook.net/en_US/sdk.js').subscribe(() => {
console.log("I'm ready to work with FB SDK");
}, (error) => {
console.log('Something wrong', error);
});
}
}It's also possible to use retry method of RxJS to retry injection script when it's failed.
import { ScriptService } from 'ngx-script-loader';
import { retry } from 'rxjs/operators';
@Component({
...
})
export class ExampleComponent {
constructor(private scriptService: ScriptService) {
this.scriptService.loadScript('https://connect.facebook.net/en_US/sdk.js')
.pipe(
retry(1)
)
.subscribe(() => {
console.log("I'm ready to work with FB SDK");
}, (error) => {
console.log('I tried 2 times but no luck');
});
}
}Some 3rd party libraries need to read some attributes from their script tag itself. It's also possible to add custom attributes to script tag with ScriptService:
this.scriptService.loadScript('https://menus.singleplatform.com/widget', {
'id': 'singleplatform-menu',
'data-location': 'spiros-restaurant--lounge',
'data-api_key': 'ke09z8icq4xu8uiiccighy1bw'
}).subscribe();By default, ScriptService adds new script tag to the head of HTML. But you can also define target place as 3rd parameter of loadScript method. It can be a selector string or HTMLElement object.
this.scriptService.loadScript('https://menus.singleplatform.com/widget', {
'id': 'singleplatform-menu',
'data-location': 'spiros-restaurant--lounge',
'data-api_key': 'ke09z8icq4xu8uiiccighy1bw'
}, '#menu-container').subscribe();or
import { ScriptService } from 'ngx-script-loader';
@Component({
...
})
export class ExampleComponent implements OnInit {
@ViewChild() menuContainer: ElementRef;
constructor(private scriptService: ScriptService) {}
ngOnInit() {
this.scriptService.loadScript('https://menus.singleplatform.com/widget', {
'id': 'singleplatform-menu',
'data-location': 'spiros-restaurant--lounge',
'data-api_key': 'ke09z8icq4xu8uiiccighy1bw'
}, this.menuContainer.nativeElement).subscribe();
}ngx-script-loader also presents ngx-script component.
<ngx-script src="https://maps.googleapis.com/maps/api/js?libraries=places"
(load)="onReady()"
(error)="onError()"
></ngx-script>When you use ngx-script, target place for script tag is inside of ngx-script element. So, for 3rd part widgets that uses document.write, this component is the easiest and cleanist way of using them.
You can also set attributes for script tag with attributes input parameter:
<ngx-script src="https://maps.googleapis.com/maps/api/js?libraries=places"
[attributes]="spMenuAttributes"
(load)="onReady()"
(error)="onError()"
></ngx-script>class ExampleComponent {
spMenuAttributes = {
'id': 'singleplatform-menu',
'data-location': 'spiros-restaurant--lounge',
'data-api_key': 'ke09z8icq4xu8uiiccighy1bw'
}
}By default loadScript() method loads a script only once in a session. If you want to inject same script multiple times, you can use runScript() method instead.
import { ScriptService } from 'ngx-script-loader';
@Component({
...
})
export class ExampleComponent {
constructor(private scriptService: ScriptService) {
this.scriptService.runScript('https://example.com/random-news.js', {}, '#news-area').subscribe();
this.scriptService.runScript('https://example.com/random-news.js', {}, '#news-area').subscribe();
this.scriptService.runScript('https://example.com/random-news.js', {}, '#news-area').subscribe();
}
}All of the parameters of runScript() are same with loadScript().