1

I have a problem where I need to use a specific 3rd party library to generate a nonce to use the square connect api. I am having troubles finding how to load the external javascript library since they don't have a node_module that I can load like I usually do. By external library I mean something like this <script src="https://js.squareup.com/v2/paymentform " type="text/javascript"> I have not found a good way to to load this into my application so that I can use it. Any ideas on how I can solve this problem?

2 Answers2

1

A few options that I have used:

  1. Global script using angular-cli

    "scripts": [
       "global-script.js",
       { "input": "lazy-script.js", "lazy": true },
       { "input": "pre-rename-script.js", "output": "renamed-script" },
    ]
    
  2. Require in a specific module

    import { NgModule } from '@angular/core';
    ...
    require('chart.js');
    require('../../libs/chartjs-plugin-annotation');
    ...
    
  3. Add a global script at runtime based on some condition

    if (this.usesCKEditor(permissions) && !window['CKEDITOR']) {
        const url = '//cdn.ckeditor.com/4.7.3/full/ckeditor.js';
        const script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = url;
        document.body.appendChild(script);
    }
    // must check if the script has loaded before using it
    
Sumama Waheed
  • 3,579
  • 3
  • 18
  • 32
  • On option number one do you have to download the script first or can I put the link url? – Jonathan Jensen Dec 29 '17 at 19:44
  • @JonathanJensen just an FYI, you aren't allowed (by Square) to download the script and include it, so options like number 3 are going to be better for you. – tristansokol Dec 29 '17 at 19:46
  • @JonathanJensen you can put the url in option 1 also – Sumama Waheed Dec 29 '17 at 20:10
  • @tristansokol Thanks for the update. I am aware of them not allowing the downloading of their scripts which is why I asked the question. But if I did not know about it then that would have been helpful. So thank you. – Jonathan Jensen Dec 29 '17 at 20:29
  • @SumamaWaheed When I try option number one I get this error: ERROR in multi script-loader!./src/https:/js.squareup.com/v2/paymentform Module not found: Error: Can't resolve '/Users/jpjensen/Projects/build-a-bracelet/front-end/src/https:/js.squareup.com/v2/paymentform' in '/Users/jpjensen/Projects/build-a-bracelet/front-end/node_modules/@angular/cli/models/webpack-configs' @ multi script-loader!./src/https:/js.squareup.com/v2/paymentform code https://gist.github.com/jonje/703071339542964bed461742f10c5c90 – Jonathan Jensen Dec 29 '17 at 21:09
  • @Sumama Waheed Where can I put this piece of code (option 3)? – Ruthi May 19 '19 at 04:50
  • @Ruthi constructor or ngOnInit(). You can use the onload callback to know the when script has loaded – Sumama Waheed May 19 '19 at 04:53
1

First Approach:

Refer the scripts inside the angular-cli.json file.

"scripts": [
    "../path" 
 ];

Second Approach

You can create your own directive to load script as below

import { Directive, OnInit, Input } from '@angular/core';

@Directive({
    selector: '[appLoadScript]'
})
export class LoadScriptDirective implements OnInit{

    @Input('script') param:  any;

    ngOnInit() {
        let node = document.createElement('script');
        node.src = this.param;
        node.type = 'text/javascript';
        node.async = false;
        node.charset = 'utf-8';
        document.getElementsByTagName('head')[0].appendChild(node);
    }

}

HOW TO USE

<i appLoadScript  [script]="'https://js.squareup.com/v2/paymentform'"></i>

DEMO

santosh singh
  • 27,666
  • 26
  • 83
  • 129
  • Second approach works well, but I prefer the first one. Is there a way to make use of environment variables with the first approach? I need to inject in an API key. – umutesen Feb 08 '20 at 13:53