Get the Angular script that supports dynamic src downloading by utilizing the unique features

In Angular, there are methods available to dynamically load templates with variable names using ng-include. It's possible to include inline JS and CSS in the partial without any issues, but when it comes to downloading scripts with dynamic URLs, things get a bit tricky. Our requirement was to download scripts relative to the path of the .html partial that called them (for example, having a directory with the necessary files to include, and wanting the .html file to specify its required scripts).

Unlike the scenario discussed in AngularJS: How to make angular load script inside ng-include?, where a static source script is loaded in a dynamically included partial, I am looking to dynamically create the source for a script within a dynamically included partial, either through interpolation or by executing it using an Angular function.

For instance, if I'm loading a partial into my application dynamically from a directory that contains additional resources the partial depends on, instead of downloading each file separately, I want that logic to reside within the partial itself. Knowing that the browser cannot handle this task, I'll utilize ng-src and let Angular handle the heavy lifting. Instead of manually parsing every script src tag in relation to the partial, I'll define a function to generate the URLs as follows:

<script type="application/javascript" ng-src="prefixUrl('myUrl.js')"></script>

So how can I accomplish this effectively?

Answer №1

Click here for the gist

Keep in mind that this will replace the default script directive in angular, which searches for templates in your script tags. You have the option to rename the directive, but we opted not to do so (since we were injecting these services/directives into a newly bootstrapped app on the page).

This method assumes you have a way to download scripts dynamically. We are using $script, but jquery or any other similar tool would also suffice, just make sure to update the service accordingly.

Instead of the current setup, which involves employing a function prefixUrl, you can easily modify the script directive to directly prefix the URL itself (using attrs.ngSrc) without depending on the function.

An event called 'WidgetContentLoaded' (easily customizable) has been included to trigger after all the scripts have finished downloading.

Javascript

angular.module('myApp')
.run(function ($rootScope) {
    $rootScope.mixin = function(urls) {

        if (angular.isUndefined(urls) || urls == '') {
            return $q.when('no mixin url');
        }

        var deferred = $q.defer();

        //timeout our requests at 5 seconds
        var timeoutPromise = $timeout(function() { deferred.reject(null) }, 5000);

        //assuming that $script or some other downloading mechanism is available
        $script(urls, function() {
            $timeout.cancel(timeoutPromise);
            $rootScope.$safeApply(deferred.resolve(urls));
        });

        return deferred.promise;
    };

    $document.on('WidgetContentLoaded', function () {
        //add more interesting logic here...this is like $(document).ready() but for your included partial
        console.log('yay we loaded your scripts');
    });

})
.service('lazyScripts', ['$q', '$timeout', '$document', function ($q, $timeout, $document) {

    var promises = [];

    this.register = function (url) {
        promises.push($clotho.extensions.mixin(url));
    };

    $timeout(function() {
        $q.all(promises).then(function() {
            //broadcast event
            $document.triggerHandler('WidgetContentLoaded');
        })
    });
}])
.directive('script', function($parse, $rootScope) {
    return {
        restrict: 'E',
        terminal: true,
        compile: function(element, attr) {
            if (attr.ngSrc) {
                var scriptUrl = $parse(attr.ngSrc)($rootScope);
                 lazyScripts.register(scriptUrl);
            }
        }
    };
});

Your HTML

<script type="application/javascript" ng-src="prefixUrl('inlineCalledScript.js')"></script>

<style type="text/css">
    .greenListItem {
        color: #44bb44;
    }
</style>

<ul>
    <li>This is a dynamically loaded template.</li>
    <li>Kindly note that Angular must already be bootstrapped with the new script directive mentioned above. This will not function properly in your index.html file</li>
    <li class="greenListItem">Inline CSS is effective!</li>
</ul>

<!-- this should work seamlessly -->
<div ng-include="prefixUrl('anotherPartial.html')"></div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Sending asynchronous data to a child component in Angular 2

Having trouble with passing asynchronous data to a child component. I am attempting to create a dynamic form generator, but I encounter an issue when trying to fetch JSON data via an Observable and then passing it to the child component. Service: generat ...

Obtaining JSON Data Using WinJS.xhr():

I'm encountering difficulties with retrieving chat messages using winjs.xhr: function getMessage() { var time = MESSAGE_RETURNED.unixtime; if (time == 0) { time= window.parent.SESSION.unixtime; } WinJS.x ...

How to deactivate the mobile hardware back button functionality in Ionic 2

Our team has been developing a business application and we've encountered a perplexing issue. Every time we press the mobile hardware back button, our application's GUI becomes disrupted. Despite dedicating numerous hours to finding a solution, t ...

I'm having trouble executing the straightforward code I discovered on GitHub

https://github.com/Valish/sherdog-api Upon downloading the sherdog-api, I embarked on installing node.js as a prerequisite for using this new tool, despite having no prior experience with such software. Following that, I opened up the command prompt and n ...

Regularly check in with the server via ajax calls

I have a page that needs to send periodic "background" ajax requests after it is loaded. These requests should be sent at specific time intervals. Would using cron be the best option for this task, considering that I have never used it before? Are there a ...

What is the reason for me encountering an error message stating "Access-Control-Allow-Origin" does not allow this origin?

I encountered the following issue: Origin http://localhost:8080 is not allowed by Access-Control-Allow-Origin when using the code snippet below: var http = new getXMLHttpRequestObject(); var url = "http://gdata.youtube.com/action/GetUploadToken"; var se ...

Creating a JavaScript script to implement a CAPTCHA feature on Google Forms

I'm looking to implement a JavaScript solution that can prevent spam on Google Forms. The idea is as follows: Generate a random number a between 1 and 1000; Generate another random number b between 1 and 1000; Obtain input from the user, storing it a ...

Looking for a different option to Prototype's Event.observe?

Instead of using the Event.observe method from the Prototype library to bind an event, I am now exploring other options in plain JavaScript. clickElem.addEventListener("click", function(event) { //operations }); I have decided to remove Prototype fro ...

Issue with loading dynamic content on a webpage using HTML and JavaScript through AJAX

I am currently using the jQuery UI Tabs plugin to dynamically load HTML pages through AJAX. Here is the structure of the HTML code: <div id="tabs"> <ul> <li><a href="pageWithGallery.html" title="pageWithGallery">Gallery< ...

Headers cannot be set once they have already been sent in an express js application

After reviewing various responses to this query, I am baffled as to why this error keeps appearing despite having res.send() in multiple paths. In my code (expressjs 4.13), it looks something like this: var user ={ username: "some", password: "a" ...

Using Google App Script for Slides to center-align text within a text box

Currently, I am tackling a project that demands the center alignment of text within a textbox on a google slide using a google app script. The primary objective is to fetch text from a google worksheet and an image from google drive. Subsequently, combine ...

Unable to retrieve req.files using multer from the req object

I have been attempting to send a file to the server using a NodeJs script. Below are the steps I am taking. HTML <md-tab label="Upload log"> <md-content class="md-padding" id="popupContainer" ng-cloak> <h4>Send a zip file< ...

Checking if the view should be shown based on the outcome of an ajax request when the route changes in AngularJS

I am trying to implement a feature that checks if the user is logged in before displaying certain routes. If the session is not active, the user should be redirected to the log-in view. Initially, I attempted to listen to the $routeChangeStart event from ...

Is there a way to properly access and interpret a .log extension file within a React component?

import React from "react"; import "./App.css"; function FileReaderComponent() { const readLogFile = () => { if (window.File && window.FileReader && window.FileList && window.Blob) { const preview = document.getElementByI ...

"Retrieve a variable from the code-behind file and use it in the ASPX

I am attempting to retrieve a variable from the code behind page and display it in an ASPX page with HTML formatting. Here is the code I am using: Note: I have assigned a value to a StringBuilder object, stored it in a variable, and now I am trying to acce ...

Implementing image max-width and maintaining aspect ratios for responsiveness

Within the code snippet below and utilizing Bootstrap, a grid layout is defined with several .block components, each comprising an image and a title. The images are designed to be larger than the column size so that they can expand to full width for respon ...

Unlocking the potential of resizable bootstrap table columns in React

Currently utilizing a bootstrap table <div class="table-responsive"> <table class="table table-bordered"> <thead> <tr> <th>#</th> <th>Table heading</th> </tr> < ...

Discovering common elements in various arrays of objects

Details: record1 = [{"site": "The Blue Tiger", "zipcode": "E1 6QE"}, {"site": "Cafe Deluxe", "zipcode": "E6 5FD"}] record2 = [{"site": "Blue Tiger", "zi ...

Adjusting the Camera in three.js

I'm relatively new to three.js and webgl programming. I managed to create a box in three.js, which is functioning correctly. However, I encountered an issue where the box disappears when I try setting the camera position along the z-axis (e.g., camera ...

Tips for activating and setting up Bootstrap popovers

I've been trying to add some popovers to my webpage, but I'm facing a hurdle. I added a few button popovers in the footer, but nothing happens when they're clicked. I created a js file for initialization and imported it at the end of my pa ...