In my Django project I'm trying to create a page that constantly displays the current state of a certain field in a database. I'm using ajax to do that but for reason the response object I'm returning keeps coming back as undefined.
Here is my view:
def call_ajax(request):
if request.is_ajax():
userp = UserProfile.objects.get(user=request.user)
accepted = userp.recent_call.accepted
hello = "hello"
ajax_vars = {
'accepted':accepted,
'hello':hello,
}
return JsonResponse(ajax_vars)
Here is the relevant javascript:
$(document).ready(function(response){
ajax_call(response);
});
function ajax_call(response){
$.ajax({
type: 'GET',
url: '/calls/call_ajax/',
dataType: 'json',
async: true,
data: {
accepted: response.accepted,
hello: response.hello,
},
success: function(response) {
console.log(response.hello)
$('#info').html('<p>'+response.hello+'</p>');
},
error: function() {
$('#info').html('<p>An error has occurred</p>');
}
});
setInterval(function() { ajax_call(response); },10000)
}
For some reason the console is logging that the response object is undefined. Any tips?
Related
I have the following code that outputs the initialized value of my variable before it is updated by an $.ajax() callback. It seems that the 'get' is performed after the variable is logged despite how the code is written. How can I correct this? Thanks for any suggestions.
var statusUpdate = {
queries : [],
numQueries : 0,
getNumQueries : function(){
$.ajax({
type: 'get',
url: '40985839503175/planXML.txt',
cache: false,
error: function()
{
},
success: function(data){
statusUpdate.queries = $(data).find('query');
statusUpdate.numQueries = statusUpdate.queries.length;
//console.log(statusUpdate.numQueries);
}
});
} // end getNumQueries
};
statusUpdate.getNumQueries();
console.log(statusUpdate.numQueries)
var statusUpdate = {
queries : [],
numQueries : 0,
getNumQueries : function(){
$.ajax({
type: 'get',
url: '40985839503175/planXML.txt',
cache: false,
error: function()
{
},
success: function(data){
statusUpdate.queries = $(data).find('query');
statusUpdate.numQueries = statusUpdate.queries.length;
console.log(statusUpdate.numQueries);
}
});
} // end getNumQueries
};
Uncomment the logger in the success callback. Otherwise the log may run before the ajax call gets a chance to complete.
Ajax calls are asynchronous. I'm guessing that you are seeing 0 in your console?
Put the console.log inside the success function. But I'd recommend passing a callback or returning the promise object (it will require you to restructure your JavaScript).
var statusUpdate = {
queries : [],
numQueries : 0,
getNumQueries : function(){
$.ajax({
type: 'get',
url: '40985839503175/planXML.txt',
cache: false,
error: function()
{
},
success: function(data){
statusUpdate.queries = $(data).find('query');
statusUpdate.numQueries = statusUpdate.queries.length;
console.log(statusUpdate.numQueries)
}
});
} // end getNumQueries
};
statusUpdate.getNumQueries();
UPDATE: Here's what I meant by using a promise. For more info, see Deferred Object and the jQuery.ajax() documentation
var statusUpdate = {
queries : [],
numQueries : 0,
getNumQueries : function(){
var deferred = new $.Deferred();
$.ajax({
type: 'get',
url: '40985839503175/planXML.txt',
cache: false
}).done(function(data){
statusUpdate.queries = $(data).find('query');
statusUpdate.numQueries = statusUpdate.queries.length;
deferred.resolve();
).fail(function () {
deferred.reject();
});
return deferred.promise();
} // end getNumQueries
};
statusUpdate.getNumQueries().done(function () {
console.log(statusUpdate.numQueries)
});
Ok, I guess I can't make it work as envisioned. I added a complete function but it seems like kind of a workaround. Is this a reasonable practice? Thanks.
I have a link:
<a class="tag" wi_id="3042" wl_id="3693" for_user_id="441" href="#a">
which triggers an ajax call
$(".tag").click(function() {
var for_user_id = $(this).attr("for_user_id");
var wl_id = $(this).attr("wl_id");
var wi_id = $(this).attr("wi_id");
$.ajax({
type: "POST",
url: "/ajax/actions/tag.php",
data: {
'for_user_id': 'for_user_id',
'wl_id': 'wl_id',
'wi_id': 'wi_id'
},
success: function(data){
$(this).text("You've tagged this");
$(this).closest('.gl_buttons_holder').toggleClass('gl_buttons_holder gl_buttons_holder_tagged');
$(this).closest('.gl_buttons').addClass('tagged');
}
});
return false;
});
But in the console I see the following:
TypeError: e is undefined
The ajax file gets processed but the POST data is blank, and the success actions do not happen, so it gets posted with zeros and classes are not changed
I have stared and stared... anything obvious?
this is not passed automatically to the AJAX callback function. You can use the context: parameter to tell jQuery to pass it:
$.ajax({
type: "POST",
url: "/ajax/actions/tag.php",
data: {
'for_user_id': for_user_id,
'wl_id': wl_id,
'wi_id': wi_id
},
context: this,
success: function(data){
$(this).text("You've tagged this");
$(this).closest('.gl_buttons_holder').toggleClass('gl_buttons_holder gl_buttons_holder_tagged');
$(this).closest('.gl_buttons').addClass('tagged');
}
});
You're sending your data wrong, don't call your variables inside single quotes.
$(".tag").click(function() {
var for_user_id = $(this).attr("for_user_id");
var wl_id = $(this).attr("wl_id");
var wi_id = $(this).attr("wi_id");
$.ajax({
type: "POST",
url: "/ajax/actions/tag.php",
data: {
'for_user_id': for_user_id,
'wl_id': wl_id,
'wi_id': wi_id
},
success: function(data){
$(this).text("You've tagged this");
$(this).closest('.gl_buttons_holder').toggleClass('gl_buttons_holder gl_buttons_holder_tagged');
$(this).closest('.gl_buttons').addClass('tagged');
}
});
return false;
});
I've encounted a strange problem with Ko mapping.
I use this piece of code:
var PList = [{ "Region": { "RegionName": "SomeRegion" }, "CDetails": {}, "Category": { "Name": "SomeCategory" }, "PSource": 1, "PDate": "0001-01-01T00:00:00"}];
var PViewModel = ko.mapping.fromJS(search('someSearch', 'True'));
var PViewModel2 = ko.mapping.fromJS(PostList);
function search(queryString, isFirst) {
$.ajax({
type: 'POST',
url: 'url',
data: { 'searchQuery': queryString },
dataType: 'json',
success: function (dt) {
if (isFirst != 'True') {
ko.mapping.fromJS(dt, PostsViewModel);
}
return dt;
}
});
};
Strangely I see 2 outcomes:
When I go to PViewModel (the one populated by ajax) I see it as undefined
When I go to PViewModel2 (the one with static data) I can see the objects as expected
*The static data of PViewModel2 is just a copy of the data returned by the ajax post.
My questions are:
Does anyone know why is this so? And how to fix it?
Furthermore, is the if (isFirst != 'True') clause the right way to init the ko view model?
You are dealing with an asynchronous operation (an Ajax request). These operations do not have return values. Therefore, this can never work:
ko.mapping.fromJS(search('someSearch', 'True'));
That's what the success callback is for. Incoming data can only be handled there.
function search(queryString, targetObservable) {
$.ajax({
type: 'POST',
url: 'url',
data: { 'searchQuery': queryString },
dataType: 'json',
success: function (dt) {
ko.mapping.fromJS(dt, targetObservable);
}
});
};
search('someSearch', PostsViewModel);
I got some problem while posting JSON data into MVC 4 controller.
Below method is working fine in Firefox but unfortunately failed in IE 9
The JavaScript :
var newCustomer = {
CustName: $("#CustName").val(),
CustLocalName: $("#CustLocalName").val(),
CustNumber: $("#CustNumber").val(),
CountryID: $("#SelectCountry").val(),
City: $("#City").val()
};
$.ajax({
url: '#Url.Content("~/CustomerHeader/CreateCustomerHeader")',
cache: false,
type: "POST",
dataType: "json",
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(newCustomer),
success: function (mydata) {
$("#message").html("Success");
},
error: function () {
$("#message").html("Save failed");
}
});
and this is my controller :
public JsonResult CreateCustomerHeader(CustomerHeader record)
{
try
{
if (!ModelState.IsValid)
{
return Json(new { Result = "ERROR", Message = "Form is not valid! Please correct it and try again." });
}
RepositoryHeader.Update(record);
return Json(new { Result = "OK", Record = record});
}
catch (Exception ex)
{
return Json(new { Result = "ERROR", Message = ex.Message });
}
}
the "data" variable as in public JsonResult CreateCustomerHeader(CustomerHeader **data**) is getting NULL but while using FireFox it holds the correct value.
UPDATE : New method trying using $.post
function CreateNewCustomer(newCustomer) {
$.post("/CustomerHeader/CreateCustomerHeader",
newCustomer,
function (response, status, jqxhr) {
console.log(response.toString())
});
}
Based off the bit that you've shown, this is a simplified variation that may work more consistently, using jQuery.post() (http://api.jquery.com/jQuery.post/):
var data = {
CustName: $("#CustName").val(),
CustLocalName: $("#CustLocalName").val(),
CustNumber: $("#CustNumber").val(),
CountryID: $("#SelectCountry").val(),
City: $("#City").val()
};
$.post({
'#Url.Action("CreateCustomerHeader", "CustomerHeader")',
data,
function(response, status, jqxhr){
// do something with the response data
}).success(function () {
$("#message").html("Success");
}).error(function () {
$("#message").html("Save failed");
});
$.post() uses $.ajax as it's base, but abstracts some of the details away. For instance, $.post calls are not cached, so you don't need to set the cache state (and setting it is ignored if you do). Using a simple JavaScript object lets jQuery decide how to serialize the POST variables; when using this format, I rarely have issues with the model binder not being able to properly bind to my .NET classes.
response is whatever you send back from the controller; in your case, a JSON object. status is a simple text value like success or error, and jqxhr is a jQuery XMLHttpRequest object, which you could use to get some more information about the request, but I rarely find a need for it.
first of all I would like to apologize #Tieson.T for not providing details on JavaScript section of the view. The problem is actually caused by $('#addCustomerHeaderModal').modal('hide') that occurred just after ajax call.
The full script :
try{ ..
var newCustomer =
{
CustName: $("#CustName").val(),
CustLocalName: $("#CustLocalName").val(),
CustNumber: $("#CustNumber").val(),
CountryID: $("#SelectCountry").val(),
City: $("#City").val()
};
$.ajax({
url: '/CustomerHeader/CreateCustomerHeader',
cache: false,
type: "POST",
dataType: "json",
data: JSON.stringify(newCustomer),
contentType: "application/json; charset=utf-8",
success: function (mydata) {
$("#message").html("Success");
},
error: function () {
$("#message").html("Save failed");
}
});
}
catch(Error) {
console.log(Error.toString());
}
//$('#addCustomerHeaderModal').modal('hide')//THIS is the part that causing controller cannot retrieve the data but happened only with IE!
I have commented $('#addCustomerHeaderModal').modal('hide') and now the value received by controller is no more NULL with IE. Don't know why modal-hide event behave like this with IE9.
Thanks for all the efforts in solving my problem guys :-)
Is there a way to debug or get an error when wijdatasource complete is request with a wijhttpproxy and have some problems with the data?
data: new wijdatasource({
dynamic: true,
proxy: new wijhttpproxy({
url: "#Url.Action("List")",
type: "POST",
dataType: "json"
}),
reader: {
read: function (datasource) {
alert(datasource);
var count = datasource.data.TotalRowCount;
datasource.data = datasource.data.Items;
datasource.data.totalRows = count;
new wijarrayreader([
{ name: "CdCF", mapping: "CdCF" },
{ name: "Descrizione", mapping: "Descrizione" }
]).read(datasource);
}
}
})
With the internet explorer debugger I can see the call is made with a 200 HTTP response to the List action but "alert(datasource);" is never executed.
I want to get the error that make the datasource not parse the data (if this is the error).
In a standard ajax call I could have had an "error" callback to try to debug the problem.
$.ajax({
error: function (error) {
alert("error: " + error);
},
url: '#Url.Action("List")',
success: function (code) {
var myModel = {
items: eval(code)
};
}
});
I think you want to do a Get instead of a Post.
proxy: new wijhttpproxy({
url: "#Url.Action("List")",
type: "Get",
dataType: "json"
}),
What I did is that I caught the error in the controller an modified the object I was sending back to have a "success" boolean that I checked on the read function so that if datasource.data.success was true, then I would process the data if not I would spit out a message. You would have to put everything in your controller action inside a try-catch block.