2

I have three files in my python flask application built on angular js for front end.

app.py

    import json
    import flask
    import numpy as np


    app = flask.Flask(__name__)


    @app.route("/")
    def index():
        return flask.render_template("index.html")


    if __name__ == "__main__":
        import os

        port = 80

        # Open a web browser pointing at the app.
        os.system("open http://localhost:{0}".format(port))

        # Set up the development server on port 80.
        app.debug = True
        app.run(port=port)

index.html

<!DOCTYPE html>
    <html ng-app="gemStore">
      <head>
        <script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js'></script>
        <script type="text/javascript" src="static/app.js"></script>
      </head>

      <body ng-controller="StoreController as store">
            <div class="list-group-item">
                   <h3>{{store.product.name}} <em class="pull-right">25</em></h3>
            </div>
      </body>
    </html>

app.js

(function() {
      var app = angular.module('gemStore', []);

      app.controller('StoreController', function(){
                  this.product = gem;
              }
      );


      var gem =  {
                      name: "Chicken",
                      price: 123.11,
                      color: "White"
                  };

    })();

When I run this application, the presence of the following line causes an error:

<h3>{{store.product.name}} <em class="pull-right">25</em></h3>

I get an error saying. jinja2.exceptions.UndefinedError UndefinedError: 'store' is undefined

This is strange because the same front end application would run properly if I didn't use a python flask server. Also, I checked the html file is correctly referencing the app.js file by testing an alert.

user3422637
  • 3,967
  • 17
  • 49
  • 72

2 Answers2

4

Flask uses Jinja2 to render HTML template, which like AngularJS, uses {{ + }} denote variables being passed through via render_template.

In this particular case, you're trying to access store.product.name which is a variable from within AngularJS. However, because Jinja2 (i.e. Flask) processes the HTML first it tries to treat it as a Flask variable being passed to the template renderer.

If you want the HTML to print out with {{store.product.name}} to be a variable parsed by AngularJS, you'll need to tell Jinja2 that: "Hey, I don't want you to parse this as a Flask variable."

There are a few different ways of doing that.

First, you can add the {{ `}}`` as escaped text:

<h3>{{ '{{' }}store.product.name{{ '}}' }} <em class="pull-right">25</em></h3>

This will add {{ and }} around the string store.product.name and be rendered as {{store.product.name}}

Alternatively, you can write a Jinja2 Filter that tells it to not parse the variable and return the raw-string. For example, Flask-Triangle is a Flask extension that includes an angularjs filter:

http://flask-triangle.readthedocs.org/en/develop/tutorial/part1.html

however one can be easily written yourself.

robodude666
  • 178
  • 1
  • 13
  • Thanks a lot for this. This is super helpful. However, when I tried importing flask.ext.triangle I got an error that it doesn't exist: ImportError: No module named flask.ext.triangle I can't find any resources to download triangle. – user3422637 Jan 03 '15 at 00:25
  • You can install it either via pip or manually downloading it. See the [installation](http://flask-triangle.readthedocs.org/en/develop/installing.html) instructions on flask-triangle's docs website. – robodude666 Jan 03 '15 at 00:34
  • This package is different from the one you shared. They are named same and do similar things but documentation differs for this: http://flask-triangle.readthedocs.org/en/latest/glance.html#the-angular-filter For this package, flask.ext.triangle exists but flask.ext.triangle.Triangle does not exist. The way include angular tags for this package is very verbose and affects the simplicity of the view. – user3422637 Jan 03 '15 at 00:48
2

Got it.

The answer is here: AngularJS-Twig conflict with double curly braces

Modified app.js to

(function() {
  var app = angular.module('gemStore', []);

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

  app.controller('StoreController', function(){
              this.product = gem;
          }
  );


  var gem =
              {
                  name: "Chicken",
                  price: 123.11,
                  color: "White"
              }
  ;

})();

Modified index.html to:

<!DOCTYPE html>
<html ng-app="gemStore">
  <head>
    <script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js'></script>
    <script type="text/javascript" src="static/app.js"></script>
  </head>

  <body ng-controller="StoreController as store">
        <div class="list-group-item">
               <h3>{[{store.product.name}]} <em class="pull-right">25</em></h3>
        </div>
  </body>
</html>
Community
  • 1
  • 1
user3422637
  • 3,967
  • 17
  • 49
  • 72