Good afternoon!
I am working on a Flask application. In one of the templates (HTML file) called reserve.html
, I have a block of embedded JS that works perfectly fine. When I try to move it to a separate file (static/reserve.js
)to make the HTML more readable, I get this “uncaught error” in Chrome’s console:
Uncaught SyntaxError: Expected property name or '}' in JSON at position 1 (line 1 column 2)
at JSON.parse (<anonymous>)
at reserve.js:1:21
(reserve.js
is placed correctly in the “static” folder as required by Flask)
This is the line to which the error is referring (line 1 of reserve.js
where I use JSON to convert a Python dict to a JS object):
var day_list = JSON.parse('{{ day_list|tojson }}');
The dict comes from a Python file daylist.py
and the data is sent through the Flask app main.py
to the reserve.html
template. From there, it is parsed into JS object using JSON string, as shown in the previous line.
I have tried several methods of fixing quotes (to avoid multiple ” or ‘ clashing with each other) and the error did not go away.
Here is reserve.html
with JS embedded, and it works:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>Make a reservation</h1>
<h2>Choose a day:</h2>
<script>
var day_list = JSON.parse('{{ day_list|tojson }}');
function today(button_id, div_id) {
var button = document.getElementById(button_id);
var div = document.getElementById(div_id);
if (div.style.display == "block") {
div.style.display = "none";
button.style.backgroundColor = "white";
} else {
div.style.display = "block";
button.style.backgroundColor = "blue";
}
for (const day in day_list) {
if (day_list[day].num != button_id) {
document.getElementById(day_list[day].num).style.backgroundColor = "white";
document.getElementById(day_list[day].name).style.display = "none";
}
}
}
for (const day in day_list) {
console.log(day_list[day]);
}
</script>
{% for day in day_list %}
<form id="{{ day.order }}" method="POST">
<input
type="button"
id="{{ day.num }}"
onclick="today(button_id='{{ day.num }}', div_id='{{ day.name }}')"
value="{{ day.num }}"
style="background-color: white;"
>
<div id="{{ day.name }}" style="display: none;">
<label>Hello</label>
</div>
</form>
{% endfor %}
</body>
</html>
If it helps, also, here is the relevant part of main.py
:
from flask import Flask, render_template
from daylist import list_days
app = Flask(__name__)
@app.route('/create-reservation/', methods = ["GET", "POST"])
def create_reservation():
# if request.method == "POST":
# name = request.form.get("name")
# date = request.form.get("date")
# hours = request.form.get("hours").split()
# courts = request.form.get("courts").split()
# reserve(name, date, hours, courts)
day_list = list_days()
return render_template('reserve.html', day_list = day_list)
if __name__ == "__main__":
app.run(debug=True)
Now, here is reserve.html
with the JS script linked instead of embedded:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="{{ url_for('static', filename='reserve.js') }}"></script>
</head>
<body>
<h1>Make a reservation</h1>
<h2>Choose a day:</h2>
{% for day in day_list %}
<form id="{{ day.order }}" method="POST">
<input
type="button"
id="{{ day.num }}"
onclick="today(button_id='{{ day.num }}', div_id='{{ day.name }}')"
value="{{ day.num }}"
style="background-color: white;"
>
<div id="{{ day.name }}" style="display: none;">
<label>Hello</label>
</div>
</form>
{% endfor %}
</body>
</html>
And this is static/reserve.js
:
var day_list = JSON.parse('{{ day_list|tojson }}');
function today(button_id, div_id) {
var button = document.getElementById(button_id);
var div = document.getElementById(div_id);
if (div.style.display == "block") {
div.style.display = "none";
button.style.backgroundColor = "white";
} else {
div.style.display = "block";
button.style.backgroundColor = "blue";
}
for (const day in day_list) {
if (day_list[day].num != button_id) {
document.getElementById(day_list[day].num).style.backgroundColor = "white";
document.getElementById(day_list[day].name).style.display = "none";
}
}
}
for (const day in day_list) {
console.log(day_list[day]);
}
Please leave a comment if you’d like any more details that might be helpful.