user2320607 user2320607 - 4 months ago 46
AngularJS Question

render <script> tag in angularjs

I'm trying to add paypal's pay button to my angularjs app,

$scope.paypal ='<script async="async" src="https://www.paypalobjects.com/js/external/paypal-button.min.js?merchant=DJOEURGOJ97S"'+
'data-button="buynow"'+
'data-name="socks"'+
'data-quantity="1"'+
'data-amount="{{dollarValue}}"'+
'data-currency="USD"'+
'data-shipping="0"'+
'data-tax="0"'+
'data-callback="https://gamerhoic.com/ipn/data.php"'+
'></script>';


It would be so awesome IF it was just that easy.

I've tried a number of suggestions including adding ng-santize and $sce.trustAsHtml;

$sce.trustAsHtml('<script></script>');


I read through Binding data in Angular js in string added via $sce.trustAsHtml thoroughly but it's a bit more complex than what I'm doing

using $sce.trustAtHtml nothing renders. If I add {{paypal}} I obviously get the $scope.paypal '' text displayed

<div bind-unsafe-html="paypal">{{paypal}}</div>

Answer

Best approach will be create a directive, then from in the directive you can use angular.element (basically jQuery lite) to add the script to the directive element. Following should work out well:

angular.module('myApp')
.directive('paypal', [function(){
    return {
        scope: {
            dollarValue: '@'
        },
        link: function($scope, iElm, iAttrs, controller) {
            var script = '<script async="async" src="' + 
                'https://www.paypalobjects.com/js/external/' + 
                'paypal-button.min.js?merchant=DJOEURGOJ97S"'+ 
                'data-button="buynow"'+
                'data-name="socks"'+
                'data-quantity="1"'+ 
                'data-amount="' + $scope.dollarValue + '"'+
                'data-currency="USD"'+ 
                'data-shipping="0"'+
                'data-tax="0"'+
                'data-callback="https://gamerhoic.com/ipn/data.php"'+
                '></script>';

            var scriptElem = angular.element(script)
            iElm.append(scriptElem)
            scriptElem.on('ready', ...)
        }
    };
}]);

Notice this directive has isolate scope, and it is assigning it's dollarValue scope property to the string value of the parent's (so you can re-use directive)

Then in your view html, use the new custom directive as an element or attribute, specifying the dollarAmt:

<paypal dollarAmt="{{dollarAmt}}"></paypal>

or

<div paypal dollarAmt="{{dollarAmt}}"></div>

You should see your script tag get appended to it. You could also replace the containing element in the directive (reassign element in link fn to whatever you want.)

Check out this guide to creating custom directives, it's really cool

UPDATE

Looks like to create these script tags it's more foolproof to use document.createElement() rather than angular.element (see here)

I changed the directive above to use this code and was able to see the paypal button appear on the page:

var scriptElem = angular.element(document.createElement('script'))
scriptElem.attr("src", scriptUrl) // set var appropriately
element.append(scriptElem)
Comments