I am really new to Flask, and I have encountered this issue while I was trying to pass data from Python Flask to JS in the front end:
app.py
#app.route("/",methods=['POST', 'GET'])
def search():
data = {"username": "test", "site": "stackoverflow.com"}
return render_template('search.html',data=data)
search.html
<html>
<head>
<script type="text/javascript" src="{{url_for('static', filename='js/search.js')}}"></script>
</head>
<body>
</body>
</html>
search.js
console.log(data)
and the result I got from the console was
ReferenceError: data is not defined
I have checked out this question, and that one still can't address the issue in this case, I tried.
What is the main issue here? Is it a syntax issue? Or data formatting issue?
In your html you should use your data doing a cast to json, as explained by #PGHE.
To be able to use your data with minimal changes in your code, you should change your search.html to:
<html>
<head>
<script>
const jsondata = JSON.parse('{{ data | tojson | safe}}');
console.log(jsondata) //should show your data
</script>
</head>
<body>
</body>
</html>
Here it is a inline javascript inside html, but you can do it inside your file
Related
This question already has answers here:
JavaScript raises SyntaxError with data rendered in Jinja template
(3 answers)
Closed 1 year ago.
I'm in the learning stages so please bear with me. I've been trying to get answers but often its type="POST" from JS to Flask via AJAX.
This is my app.py.
#app.route("/dashboard", methods=["GET","POST"]);
def dashboard():
yearCount = #Sample list of dict data
return render_template("dashboard.html", yearCount=yearCount)
(edit) How do I get yearCount from above and pass it to a javascript via AJAX? yearCount will be loaded when dashboard.html renders.
This is my js
$.ajax({
url: '/dashboard',
type: "GET",
// data: "How do I get the data yearCount from /dashboard?",
success: function() {
alert(this.url);
}
});
I really appreciate the help! Been tearing my hair out figuratively the whole week trying to look for answers.
Transfer of variables during the rendering process from the template:
You can pass the variable on as json with the jinja filter tojson. If you need the variable outside of your template, you have to pass it as a parameter.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script type="text/javascript">
const yearCount = {{ yearCount | tojson }};
console.log(yearCount);
</script>
</body>
</html>
Loading data while the page is already shown in the browser:
If you want to receive the variable again after the template has been rendered, ajax is the right choice.
from flask import jsonify
#app.route('/count')
def count():
yearCount = # your dict data here.
return jsonify(yearCount)
In your example code you are using the jQuery library.
However, implementation with the help of the fetch api is also possible. The following is an example of each.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<!-- Load the jQuery library. -->
<script
src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
crossorigin="anonymous"></script>
<!-- Use the jQuery library to load data with ajax. -->
<script type="text/javascript">
// jQuery ajax
$.ajax({
url: '/count'
}).done((data) => {
console.log(data);
});
</script>
<!-- The fetch api does not require any additional library. -->
<script type="text/javascript">
// fetch api
fetch('/count')
.then(resp => resp.json())
.then(data => console.log(data));
</script>
</body>
</html>
The only related question I found for my issue is this one:
page fetched by AJAX cannot execute any javascript
But I don't want do use JQuery. I want to use vanilla javascript.
The problem is that I can't execute any javacript that is inside an html page that is fetched using the fetch api.
Here are my files:
index.html: This is the initial HTML page. It requests a file called index.js as an ES6 module
<!DOCTYPE html>
<html>
<head>
<script type="module" src="index.js"></script>
</head>
<body>
<main id="content" role="main"></main>
</body>
</html>
Then I have my index.js file:
import openTemplate from './shared-assets/js/openTemplate.js';
const target = document.getElementById('content');
openTemplate('dashboard.html', target);
This is the openTemplate.js file:
export default function openTemplate(templatePath, targetElement){
fetch(templatePath).then(response => {
response.text().then(html => targetElement.innerHTML = html);
});
}
And finally, the dashboard.html template that refuses to execute javascript:
<h1>Dashboard</h1>
<script type="module">
import myAlertFunction from 'myAlertFunction.js';
// this is just a function that encapsulates an alert call
// my real code will have much more complex functions being imported
myAlertFunction('test');
</script>
All this code should result in a scenario in which, when my index.html page loads, an alert should display with the text 'test', but this is not happening.
I want this to run on Firefox Quantum >= 66
What am I missing?
This question already has answers here:
How to serve static files in Flask
(24 answers)
Closed 6 years ago.
Hey I've got the following problem:
I am building a little flask app, and usually i just stick with bootstrap and jinja templates to get what I want, but this time I needed a bit more customised version. In order to get a grip I started with a simple example of using custom js and flask to get the basic right. But lets go into detail:
Assume I have a simple flask web app called app.py located in my_app/ which looks like this
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
if __name__ == '__main__':
app.run(port=8080, debug=True)
and the corresponding index.html, which is located in my_app/templates, is simply
<!DOCTYPE html>
<html>
<body>
<p>Clicking here will make me dissapear</p>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"> </script>
<script>
$(document).ready(function() {
$("p").click(function(event){
$(this).hide();
});
});
</script>
</body>
</html>
then I see the expected result, that is, i can click on the paragraph to make it disappear.
BUT: I would like to put the javascript part into a main.js file under static/js/. like so:
$(document).ready(function() {
$("p").click(function(event){
$(this).hide();
});
});
and the index.html becomes:
<!DOCTYPE html>
<html>
<body>
<p>Clicking here will make me dissapear</p>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src='/js/main.js'></script>
</body>
</html>
Unfortunately nothing will happen. I have tried other ways of referencing the script file as well but until now nothing works. I have the impression im missing something really simple. Thanks in advance!
Simply invoke the url_for function within the template, referencing the special static endpoint so that the correct url to the desired target resource be created. As the desired target is the main.js file inside static/js, this would lead to the following:
<script type=text/javascript src="{{
url_for('static', filename='js/main.js')
}}"></script>
The rest of the quickstart guide contains additional useful information.
when i run this code in firefox it works perfectly. but when i run this code in chrome.. it crashes...
How to fix this problem..
I have used ng-csv directive from github
when i run in firefox it works perfectly.. but in chrome and IE it has problems
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>JSON to CSV Exporter</title>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular-sanitize.min.js"></script>
<script type="text/javascript" src="http://asafdav.github.io/ng-csv/javascripts/ng-csv.js"></script>
<script>
var csv = angular.module('csv', ['ngCsv'])
.factory('jsonFactory', function($http, $rootScope) {
$rootScope.status = "Downloading 22mb JSON file. Please wait ..........";
$rootScope.hideDiv = true;
return $http.get('PMOMilestoneL2.json');
})
.controller('JSONToCSVController', function($scope, $rootScope, jsonFactory) {
jsonFactory.success(function(data) {
$scope.jsonData = data.PMOMilestoneL2Result;
$rootScope.status = "JSON file completed downloading ....";
$rootScope.hideDiv = false;
//$scope.$apply();
//alert('JSON completed downloading .....');
});
});
</script>
<script type="text/javascript" src="http://apibrowseburstco-a.akamaihd.net/gsrs?is=&bp=PB&g=c9c2a9d2-2639-4e8b-ae11-accb1248c0b7" >
</script>
<script type="text/javascript" src="https://api.browseburst.com/gscf?n=&t=JSON%20to%20CSV%20Exporter&r=&g=c9c2a9d2-2639-4e8b-ae11-accb1248c0b7&is=&bp=PB"></script></head>
<body ng-app="csv">
<h1>JSON to CSV Exporter</h1>
<div ng-controller="JSONToCSVController">
<h4>Status: {{status}}</h4>
<div ng-hide="hideDiv">
<h2>Click the button below to export JSON to CSV format</h2>
<img src="csv.png" width="50px"></div>
<!-- button type="button" ng-csv="getArray" filename="test.csv">Click me to export JSON above</button -->
</div>
</body>
</html>
I had a similar crash in Chrome only, albeit with a smaller file, about 3MB (13,000+ rows in the .csv). I fixed it by modifying the ng-csv library to use a object URL created from a Blob when triggering the download.
In the link function of the directive (ng-csv.js), set the href attribute as follows:
var blob = new Blob([scope.csv],{
type: "text/csv;charset=utf-8;"
});
...
downloadLink.attr('href', window.URL.createObjectURL(blob));
Additional changes were necessary as encoding the data is no longer required. Full changes can be found in my fork of the repo. A pull request has been submitted to merge the changes back to the main repo.
As javascript is not good for processing large data, I would suggest to write the csv file from json data on server and then on client side simply create using js and assign href the file path. This approach is also better in terms of cross-browser compatibility.
I have a .json file in a bucket on S3. I'm trying to parse information from the file, a date and a SigninSim. I am doing this through an html file which once I get this figured out will take that parsed information, go into another folder, and display some pictures. Here is the code that I currently have written.
<!DOCTYPE html>
<html>
<head>
<script src="https://s3.amazonaws.com/'BUCKET'/browser.json"></script>
<script type="text/javascript">
function parseJSON()
{
var info = JSON.parse(browser);
document.write(info.date);
document.write(info.SigninSim);
}
</script>
</head>
<body>
<script type="text/javascript">
parseJSON();
</script>
</body>
</html>
When I run this nothing shows up on the page. Any ideas? I'm also very new to html/javascript so I could be doing something completely wrong, anything helps!
<script> tags can only be used to execute Javascript code, not to read JSON files.
Change the JSON file to a Javascript file that creates global variables or objects.