3

I have the following structure and code :

project/
       app.py
       templates/
                /index.html
       static/
             /angular.js

index.html

<!doctype html>
<html ng-app="myApp">
<head>
    <meta charset="utf-8"/>
    <title>My App</title>
</head>
<body ng-controller="myCtrl as ctrl">
    <div>
        {{ctrl.foo}}
    </div>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.js"></script>
    <script type="text/javascript">

        angular.module('myApp', [])
        .controller('myCtrl', [function () {
            var self = this;
            self.foo = 10;
        }]);
    </script>
</body>
</html>

and app.py

from flask import Flask
app = Flask(__name__)
from flask import render_template

@app.route('/')
def hello_world():
    return render_template('index.html')

if __name__ == '__main__':
    app.run(debug=True)

Whatever I do, I still have the following error : UndefinedError: 'ctrl' is undefined which I guess is due to the fact that Flask does not load the angular.js

I also tried with the static path

<script type=text/javascript src="{{url_for('static', filename='angular.js')}}"></script> and <script type=text/javascript src="../static/angular.js"></script>

But still no sucess... Any ideas ?

Orelus
  • 963
  • 1
  • 13
  • 23
  • I think angular is loaded correctly: The error "UndefinedError..." looks like is angular's. Even more, if angular.js is not loaded, on the html you would see `{{ctrl.foo}}`. The html works fine on [jsfiddle](http://jsfiddle.net/4tdhtgfd/) – fernandezr Nov 11 '14 at 20:03
  • I tried a `typeof angular` with `debug=False` in the console which returned `undefined`. I also tried on plnkr and with `python -m SimpleHTTPServer` and it works fine. So the only option left is **Flask**, I am a bit confused ... – Orelus Nov 11 '14 at 20:13

1 Answers1

8

When you put

{{ctrl.foo}}

in your template, Jinja looks for a context variable named ctrl. Your hello_world endpoint doesn't provide any such variable.

If you would like ctrl to be processed by Angular instead of by Jinja, you need to tell Jinja to include the curly braces in the rendered HTML. This can be done by surrounding what you have in additional curly braces.

{{ '{{ctrl.foo}}' }}

If you don't want all of the curly braces, you have a couple of other options.

You can use Jinja's raw and endraw directives to output its contents exactly as provided.

{% raw %} {{ctrl.foo}} {% endraw %}

The other option is to change the symbols Angular looks for.

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

app.config(['$interpolateProvider', function($interpolateProvider) {
  $interpolateProvider.startSymbol('[[');
  $interpolateProvider.endSymbol(']]');
}]);

This would allow you to use

[[ctrl.foo]]
Freek Wiekmeijer
  • 4,556
  • 30
  • 37
dirn
  • 19,454
  • 5
  • 69
  • 74
  • 1
    Thanks a lot! I was convinced that the error was related to the angular.js loading process. PS : I renamed the title to "Error Angular.js with Flask" – Orelus Nov 11 '14 at 20:19
  • Thanks a lot...It saved my day – Ajay Jan 26 '16 at 07:22