31

I working on a web project using Python and Flask. I was just wondering if I can access parameters sent by python in my external javascript files? It's working well with html files or with js embedded in html files but not when javascript is extern.

See below.

The python code

@app.route('/index')
def index():
    return render_template('index.html', firstArg = 2, secondArg = 3)

The index.html code

...
<body>
    <p>The first arg is {{firstArg}}.</p>
    <script src="index.js"></script>
</body>
...

And the index.js file

window.onload=function(){
    console.log('{{secondArg}}');
};

So the first arg is correct within the html file but the second doesn't work in the js file. The browser is showing Unexpected token {.

Maybe it's not possible to use it in external js?

Otherwise I would need to insert the secondArg as an input data in html and get it within the js file but it's not very clean.

If someone can help, thanks.

Loric
  • 1,678
  • 8
  • 28
  • 48

2 Answers2

29

The index.js is probably not served by your flask instance, but it is most definitely not processed by your templateing engine and even if it would it would not have the same context as the html it is requested for.

I think the cleanest solution would be to have an initiation function in your index.js and call it from the html file:

<body>
    <p>The first arg is {{firstArg}}.</p>
    <script type="text/javascript" src="index.js"></script>
    <script type="text/javascript">
        yourInitFunction({{secondArg}});
    </script>
</body>

You also could tell flask to route the index.js, too: @yourapp.route('index.js') just like you did with the route('/index') however this is probably not a very good idea.

t.animal
  • 3,012
  • 1
  • 24
  • 25
  • Thanks. I will adopt your solution with the call of the function from the HTML. I just have a question, what would be the effect of routing index.js ? I don't understand what you mean, I thought it was just for routes and I can't see the link with the js file. – Loric Feb 23 '14 at 13:40
  • When you add a route flask will handle the GET-Requests to the route's parameter by calling the decorated function (ie the function after the `app.route()`). So you could catch all requests to 'index.js', do some computation and let the templating engine render the javascript-file like your html files. PS: If you find my answer helpfull, I would appreciate you accepting it. – t.animal Feb 23 '14 at 15:59
  • Wow. Yes indeed, why render js files as templates when it's possible to inject like this. Much Elegant. Very clean. Amaze thanks. It also enforces a certain architutectural way of not hardcoding stuff in js files. – Félix Adriyel Gagnon-Grenier Dec 04 '18 at 16:21
  • I'm having trouble understanding what yourInitFunction would look like in your external JS file, could we provide an example? – yeamusic21 Jan 05 '23 at 18:54
  • In the context of the question: `function yourInitFunction(secondArg) {console.log(secondArg);}` – t.animal Jan 11 '23 at 08:25
3

Also, you may create index_js.html (or same index.js) file and {% include 'index_js.html' %} where you need it.

1) If you like index_js.html - use <script> here is some JS templated code </script> there. Further: {% include 'index_js.html' %} in your templated html.

2) Or if you like index.js - do <script> {% include 'index.js' %} </script>.