1

I'm looking to integrate an AngularJS web application into a number of websites. I'd like to be able to provide each website administrator with an HTML code, such as the following:

<div id='angular-integration-app'></div><script src="widget.js"></script>

With this HTML code inserted into the website, the website should load AngularJS and insert an AngularJS application as a child element of the element labeled with the ID of "angular-integration-app."

This Plunker has an implementation, however this implementation isn't working. It fails intermittently, with an error of:

Uncaught ReferenceError: angular is not defined  application.js:1
Uncaught Error: [$injector:modulerr]  angular.js:38

I've noticed that it usually works fine the first time it's loaded, but when the browser refresh button is pressed, it often fails. This is particularly true when it's not being hosted through Plunker.

Please advise on the best way to create a dynamic AngularJS application integration that works all the time.

2 Answers 2

2

This inconsistent behavior is because sometimes the page is cached and the code is executed synchonously, sometimes it does not.

To fix that, you need to wait for angular to be ready, then declare your module, and then bootstrap the document with your module. You cannot use ng-app in the HTML if the bootstrapping is executed "afterwards" (asynchronously, out of angular context). I have made the changes to show you how it should be:

var element = document.querySelector('#angular-integration-app');
angular.element(element).ready(function() {

  var app = angular.module('myapp', []);

  app.directive('customForm', function() {
    return {
      restrict: 'A',
      template: 'hello world'
    };
  });

  angular.bootstrap(element, ['myapp']);
});

http://plnkr.co/edit/7KbD1Okwx0MwhDIJXIGE?p=preview

Alternatively, if you don't want angular to mess up with your target html (and what happens if he is using another version of angularjs himself?), you could create an iFrame to isolate your angular, style, and code.

Sign up to request clarification or add additional context in comments.

2 Comments

Hello, thank you for the reply. The code you provided works in Plunker, however when I copy each file to my machine and run it using a local HTTP server, I get the same behavior as before: When a browser tab is first opened with the page, “YAHOW” is printed to the console and “hello world” shows up on the page. When the browser refresh button is pressed, an error message appears in the console saying “Uncaught ReferenceError: angular is not defined.” I suspect there's still an unresolved page cache or synchronization issue.
Oh, this is a different error. Are you loading the angular.js file before you execute this code? For instance you can load the file in the <header> and have this code in the <body>. Otherwise an easy way to fix it if you are using jQuery is to use $(document).ready( ... ) instead of angular.element( element ).ready( ... ). Or if you don't use jQuery, simply try (function() { ... })()
0

The code in this Plunker looks like it solves the problem. I'm now adding AngularJS as a child of the head element (the variable named "script"), and holding off on modifying the DIV or loading the AngularJS application until "script.onload." I incorporated some of the ideas from floribon's post into this Plunker as well.

script.onload = function() {
  // code here
};

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.