6

I do not truly understand why it is necessary to do an angular.bootsrap document, ['MyApp'] at the end of my CoffeeScript code that manages the module and controllers in the following test application:

This is the HTML:

<div ng-app='InventoryModule' ng-controller='InventoryController'>
    <ul ng-repeat='item in items'>
        <li>{{item.title}}</li>
        <li>{{item.price | currency}}</li>
    </ul>
</div>

And the CoffeeScript:

inventoryModule = angular.module 'InventoryModule', []

inventoryModule.factory 'Items', ->
    items = {}
    items.query = () -> [{title: 'Hello', price: '5'}]
    items

inventoryModule.controller 'InventoryController', ($scope, Items) ->
    $scope.items = Items.query()

angular.bootstrap document, ["InventoryModule"]

If you remove the last line, the applicatoin won't work. Why is that? This is not truly explained anywhere else.

This is a fiddle of the code: http://jsfiddle.net/dralexmv/8km8x/11/

As you can see the application actually works. If you remove the bootstrap it will stop working.

0

2 Answers 2

15

Tl;dr

Set the second drop-down in jsFiddle to "No wrap - in <head>" and you won't need angular.bootstrap line.

FIDDLE

Explanation

When Angular library is loaded it will scan the DOM looking for element with ng-app directive. When it finds one it will begin the bootstrapping proces.

In that process Angular will take the value of ng-app attribute (in your case that's InventoryModule) and will try to find an angular module with the same name. If it fails it will throw: Uncaught Error: No module: <module name>.

In your fiddle you have set the "Code Wrap" select box to "onLoad". This drop-down instructs jsFiddle when to initialize the JS code that you've put in JS frame. When it's set to "onLoad", the code will run in onLoad window event.

On the other hand, Angular bootstrapping process will run on $(document).ready(), and because $().ready event is fired before "onLoad" event, Angular will try to init the InventoryModule module before the module is even defined, and that's where the dreaded "No module" error will be thrown.

angular.bootstrap() is a manual way of doing the same thing that Angular already does in it's $().ready() handler.

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

3 Comments

Awesome, great explanation.
Your explanation certainly is correct and the modified fiddle works fine. One sidenote: You used Javascript instead of coffescript (though it is a 1-1 translation). That shouldn't make any difference, but surprisingly I cannot get the original coffescript-based example working by just switching to "No wrap - in <head>". (I also tried that when I first read the question and it didn't work either.) What am I missing? Is it a jsFiddle bug or is there a subtile difference that I overlooked?
I used JavaScript because I just can't read coffescript. :) Anyway, if you put a console.log inside the coffescript you'll see that it is evaluated only after the angular already throw an error, which means that, in JSFiddle at least, raw coffescript is evaluated only after the JS files have been loaded (and after the $().ready() event).
0

Take a look at the error console. Your code throws an exception:

Uncaught Error: No module: InventoryModule

I think it has something to do with it. Manually bootstrapping by calling angular.bootstrap seems to workaround the actual problem.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.