I'm new to Flask and AJAX and my current challenge is that when I make an AJAX request to the server my result is undefined
. I am using deferred objects to keep track of several asynchronous requests, and all are working except for the AJAX function shown below. The other two are non-AJAX. Likely problem areas in the code below are marked with >>>>
For context, I am writing the backend to a one-page animation in the browser. The template remains the same regardless of any requests (clicks) from the viewer or any data requests the animation makes on its own programmatically (periodic adding and subtracting of visual material).
Flask/Python:
from flask import Response, json, render_template
from app import app
from motifs import get_motif_list
# >>>> can/should I use two functions aimed at the same route? Not sure how to both render the template and pass data
@app.route('/')
def index():
motifs = get_motif_list(10)
return Response(json.dumps(motifs), mimetype='application/json')
@app.route("/")
def index():
return render_template("index.html")
JavaScript:
function getData() {
var deferredData = new jQuery.Deferred();
$.ajax({
type: "GET",
url: "/",
dataType: "json", // >>>> when I comment this out I get an error, when I leave it in I get a parsererror
success: deferredData.resolve(),
complete: function(xhr, textStatus) {
console.log("AJAX REquest complete -> ", xhr, " -> ", textStatus);
}
});
return deferredData; // contains the passed data >>>> currently undefined!!!
};
// DEFERRED OBJECTS
// used to perform a callback after multiple asynchronous functions
var deferredData = getData();
var deferredWindow = windowLoaded();
var deferredImages = loadImages();
// SINGLE CALLBACK AFTER MULTIPLE ASYNCHRONOUS FUNCTIONS
$.when( deferredWindow, deferredData, deferredImages ).done( function( window, data, images ) {
console.log("The window has loaded - " + window); // successful!
console.log("The data are: " + data); // >>>> undefined!
console.log("The images are: " + images); // successful!
});
UPDATE:
Thanks to @Jason P the success function in the getData
AJAX call is now success: function(data) { deferredData.resolve(data); }
and the result is no longer undefined
! Alas, it's not my data, either. I think I may have a bug (or a conceptual misunderstanding) in my Flask code because the request returns the complete text of my html template instead of my JSON data. Thoughts?
UPDATE 2
Also @Jason P's suggestion I changed the route url in Flask and the AJAX request to an alternate route: /ajax
to avoid a potential(?!) clash with the template rendering. However, the request still returns the full text of my html template. Perhaps I also need to differentiate the python/flask function names? ...will try that next. Updated code below.
Python/Flask:
@app.route('/ajax')
def index():
motifs = get_motif_list(10)
return Response(json.dumps(motifs), mimetype='application/json')
@app.route("/")
def index():
return render_template("index.html")
JavaScript AJAX url property changed to:
url: '/ajax'
UPDATE 3
I differentiated the python/flask function names so that the /ajax
route function is now called ajax()
, and the root route '/'
function is still called index()
. The JSON object now renders to the screen (instead of being passed in as a variable) and nothing from the javascript renders (presumably now missing the template rendering?)
RESOLVED
Following on comments by @Jason P the call is finally resolved and functioning. Wheew! Here is the final code:
Flask/Python
from flask import Response, json, render_template
from app import app
from motifs import get_motif_list
@app.route('/ajax')
def ajax():
motifs = get_motif_list(10)
return Response(json.dumps(motifs), mimetype='application/json')
@app.route("/")
def index():
return render_template("index.html")
JavaScript:
function getData() {
var deferredData = new jQuery.Deferred();
$.ajax({
type: "GET",
url: "/ajax",
// dataType: "json",
success: function(data) {
deferredData.resolve(data);
},
error: function (data) {
debugger;
alert("Error");
},
complete: function(xhr, textStatus) {
console.log("AJAX Request complete -> ", xhr, " -> ", textStatus);
}
});
return deferredData; // contains the passed data
};
// all else in the script remains the same as above...
Thanks!